public List <Type> FindPlugins(Type baseType) { // 如果type是null,则返回所有类型 List <Type> list = null; if (_plugins.TryGetValue(baseType, out list)) { return(list); } lock (_plugins) { if (_plugins.TryGetValue(baseType, out list)) { return(list); } list = new List <Type>(); foreach (var item in Types) { if (TypeX.Create(item).IsPlugin(baseType)) { list.Add(item); } } if (list.Count <= 0) { list = null; } _plugins.Add(baseType, list); return(list); } }
String GetName(Boolean isfull, Boolean includeDefType = true) { var method = _Method; var sb = new StringBuilder(); String name = null; if (includeDefType) { var type = method.DeclaringType ?? method.ReflectedType; if (type != null) { var tx = TypeX.Create(type); name = isfull ? tx.FullName : tx.Name; } else { name = ""; } } sb.AppendFormat("{0}.", name); sb.Append(method.Name); sb.Append("("); var ps = method.GetParameters(); for (int i = 0; i < ps.Length; i++) { if (i > 0) { sb.Append(","); } if (ps[i].ParameterType != null) { var tx = TypeX.Create(ps[i].ParameterType); name = isfull ? tx.FullName : tx.Name; } else { name = ""; } sb.AppendFormat("{0} {1}", name, ps[i].Name); } sb.Append(")"); return(sb.ToString()); }
String GetName(Boolean isfull) { Type type = Type; if (type.IsNested) { var tx = TypeX.Create(type.DeclaringType); return((isfull ? tx.FullName : tx.Name) + "." + type.Name); } else if (type.IsGenericType) { var sb = new StringBuilder(); var typeDef = type.GetGenericTypeDefinition(); var name = isfull ? typeDef.FullName : typeDef.Name; var p = name.IndexOf("`"); if (p >= 0) { sb.Append(name.Substring(0, p)); } else { sb.Append(name); } sb.Append("<"); var ts = type.GetGenericArguments(); for (int i = 0; i < ts.Length; i++) { if (i > 0) { sb.Append(","); } if (!ts[i].IsGenericParameter) { var tx = TypeX.Create(ts[i]); sb.Append(isfull ? tx.FullName : tx.Name); } } sb.Append(">"); return(sb.ToString()); } else { return(isfull ? type.FullName : type.Name); } }
/// <summary>创建快速访问成员</summary> /// <param name="member"></param> /// <returns></returns> public static MemberInfoX Create(MemberInfo member) { if (member == null) { return(null); } switch (member.MemberType) { case MemberTypes.All: break; case MemberTypes.Constructor: return(ConstructorInfoX.Create(member as ConstructorInfo)); case MemberTypes.Custom: break; case MemberTypes.Event: return(EventInfoX.Create(member as EventInfo)); case MemberTypes.Field: return(FieldInfoX.Create(member as FieldInfo)); case MemberTypes.Method: return(MethodInfoX.Create(member as MethodInfo)); case MemberTypes.Property: return(PropertyInfoX.Create(member as PropertyInfo)); case MemberTypes.TypeInfo: case MemberTypes.NestedType: return(TypeX.Create(member as Type)); default: break; } return(null); }
public Type[] CreateDuckTypes(Type interfaceType, Type[] duckedTypes) { const string TYPE_PREFIX = "Duck"; String namespaceName = this.GetType().Namespace + "." + interfaceType.Name; CodeCompileUnit codeCU = new CodeCompileUnit(); CodeNamespace codeNsp = new CodeNamespace(namespaceName); codeCU.Namespaces.Add(codeNsp); //CodeTypeReference codeTRInterface = new CodeTypeReference(interfaceType); CodeTypeReference codeTRInterface = new CodeTypeReference(TypeX.Create(interfaceType).FullName); ReferenceList references = new ReferenceList(); // 遍历处理每一个需要代理的类 for (int i = 0; i < duckedTypes.Length; i++) { Type objectType = duckedTypes[i]; //CodeTypeReference codeTRObject = new CodeTypeReference(objectType); CodeTypeReference codeTRObject = new CodeTypeReference(TypeX.Create(objectType).FullName); references.AddReference(objectType); CodeTypeDeclaration codeType = new CodeTypeDeclaration(TYPE_PREFIX + i); codeNsp.Types.Add(codeType); codeType.TypeAttributes = TypeAttributes.Public; codeType.BaseTypes.Add(codeTRInterface); // 声明一个字段 CodeMemberField codeFldObj = new CodeMemberField(codeTRObject, "_obj"); codeType.Members.Add(codeFldObj); CodeFieldReferenceExpression codeFldRef = new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), codeFldObj.Name); // 创建一个构造函数 CodeConstructor codeCtor = new CodeConstructor(); codeType.Members.Add(codeCtor); codeCtor.Attributes = MemberAttributes.Public; codeCtor.Parameters.Add(new CodeParameterDeclarationExpression(codeTRObject, "obj")); codeCtor.Statements.Add( new CodeAssignStatement( codeFldRef, new CodeArgumentReferenceExpression("obj") ) ); // 创建成员 CreateMember(interfaceType, objectType, codeType, references, codeFldRef); } #region 编译 CSharpCodeProvider codeprov = new CSharpCodeProvider(); #if DEBUG { StringWriter sw = new StringWriter(); codeprov.GenerateCodeFromCompileUnit(codeCU, sw, new CodeGeneratorOptions()); string code = sw.ToString(); Console.WriteLine(code); } #endif CompilerParameters compilerParams = new CompilerParameters(); compilerParams.GenerateInMemory = true; compilerParams.ReferencedAssemblies.Add(interfaceType.Assembly.Location); references.SetToCompilerParameters(compilerParams); CompilerResults cres = codeprov.CompileAssemblyFromDom(compilerParams, codeCU); if (cres.Errors.Count > 0) { StringWriter sw = new StringWriter(); foreach (CompilerError err in cres.Errors) { sw.WriteLine(err.ErrorText); } throw new InvalidOperationException("编译错误: \n\n" + sw.ToString()); } Assembly assembly = cres.CompiledAssembly; Type[] res = new Type[duckedTypes.Length]; for (int i = 0; i < duckedTypes.Length; i++) { res[i] = assembly.GetType(namespaceName + "." + TYPE_PREFIX + i); } return(res); #endregion }
void CreateMember(Type interfaceType, Type duckType, CodeTypeDeclaration codeType, ReferenceList references, CodeFieldReferenceExpression codeFldRef) { CodeTypeReference codeTRInterface = new CodeTypeReference(TypeX.Create(interfaceType).FullName); //// 找到duckType里面是否有公共的_obj; //FieldInfo fiObj = duckType.GetField("_obj", BindingFlags.Public | BindingFlags.Instance); //Type innerType = fiObj != null ? fiObj.FieldType : null; CodeFieldReferenceExpression fdRef = null; #region 方法 foreach (var mi in interfaceType.GetMethods()) { // 忽略专用名字的方法,如属性的get/set,还有构造函数 if ((mi.Attributes & MethodAttributes.SpecialName) != 0) { continue; } CodeMemberMethod codeMethod = new CodeMemberMethod(); codeType.Members.Add(codeMethod); codeMethod.Name = mi.Name; codeMethod.ReturnType = new CodeTypeReference(mi.ReturnType); codeMethod.PrivateImplementationType = codeTRInterface; references.AddReference(mi.ReturnType); ParameterInfo[] parameters = mi.GetParameters(); CodeArgumentReferenceExpression[] codeArgs = new CodeArgumentReferenceExpression[parameters.Length]; int n = 0; Type[] pits = new Type[parameters.Length]; foreach (ParameterInfo parameter in parameters) { pits[n] = parameter.ParameterType; references.AddReference(parameter.ParameterType); CodeParameterDeclarationExpression codeParam = new CodeParameterDeclarationExpression(parameter.ParameterType, parameter.Name); codeMethod.Parameters.Add(codeParam); codeArgs[n++] = new CodeArgumentReferenceExpression(parameter.Name); } CodeMethodInvokeExpression codeMethodInvoke = new CodeMethodInvokeExpression(FindMember(duckType, mi, codeFldRef), mi.Name, codeArgs); if (mi.ReturnType == typeof(void)) { codeMethod.Statements.Add(codeMethodInvoke); } else { codeMethod.Statements.Add(new CodeMethodReturnStatement(codeMethodInvoke)); } } #endregion #region 属性 foreach (PropertyInfo pi in interfaceType.GetProperties()) { CodeMemberProperty property = new CodeMemberProperty(); codeType.Members.Add(property); property.Name = pi.Name; property.Type = new CodeTypeReference(pi.PropertyType); property.Attributes = MemberAttributes.Public; property.PrivateImplementationType = codeTRInterface; references.AddReference(pi.PropertyType); ParameterInfo[] parameters = pi.GetIndexParameters(); CodeArgumentReferenceExpression[] args = new CodeArgumentReferenceExpression[parameters.Length]; int n = 0; foreach (ParameterInfo parameter in parameters) { CodeParameterDeclarationExpression codeParam = new CodeParameterDeclarationExpression(parameter.ParameterType, parameter.Name); property.Parameters.Add(codeParam); references.AddReference(parameter.ParameterType); CodeArgumentReferenceExpression codeArgRef = new CodeArgumentReferenceExpression(parameter.Name); args[n++] = codeArgRef; } fdRef = FindMember(duckType, pi, codeFldRef); if (pi.CanRead) { property.HasGet = true; if (args.Length == 0) { property.GetStatements.Add( new CodeMethodReturnStatement( new CodePropertyReferenceExpression( fdRef, pi.Name ) ) ); } else { property.GetStatements.Add( new CodeMethodReturnStatement( new CodeIndexerExpression( fdRef, args ) ) ); } } if (pi.CanWrite) { property.HasSet = true; if (args.Length == 0) { property.SetStatements.Add( new CodeAssignStatement( new CodePropertyReferenceExpression( fdRef, pi.Name ), new CodePropertySetValueReferenceExpression() ) ); } else { property.SetStatements.Add( new CodeAssignStatement( new CodeIndexerExpression( fdRef, args ), new CodePropertySetValueReferenceExpression() ) ); } } } #endregion #region 事件 foreach (EventInfo ei in interfaceType.GetEvents()) { fdRef = FindMember(duckType, ei, codeFldRef); StringBuilder sbCode = new StringBuilder(); sbCode.Append("public event " + ei.EventHandlerType.FullName + " @" + ei.Name + "{"); //sbCode.Append("add {" + codeFldObj.Name + "." + ei.Name + "+=value;}"); //sbCode.Append("remove {" + codeFldObj.Name + "." + ei.Name + "-=value;}"); if (fdRef == codeFldRef) { sbCode.Append("add {" + codeFldRef.FieldName + "." + ei.Name + "+=value;}"); sbCode.Append("remove {" + codeFldRef.FieldName + "." + ei.Name + "-=value;}"); } else { sbCode.Append("add {" + fdRef.FieldName + "." + codeFldRef.FieldName + "." + ei.Name + "+=value;}"); sbCode.Append("remove {" + fdRef.FieldName + "." + codeFldRef.FieldName + "." + ei.Name + "-=value;}"); } sbCode.Append("}"); references.AddReference(ei.EventHandlerType); codeType.Members.Add(new CodeSnippetTypeMember(sbCode.ToString())); } #endregion #region 递归基接口 Type[] ts = interfaceType.GetInterfaces(); if (ts != null && ts.Length > 0) { foreach (Type item in ts) { CreateMember(item, duckType, codeType, references, codeFldRef); } } #endregion }
/// <summary></summary> public static void Test() { XTrace.WriteLine("创建类型……"); #region TypeX类型 TypeX type = TypeX.Create(typeof(FastTest)); Object obj = type.CreateInstance(); Debug.Assert(obj != null, "创建实例出错!"); obj = type.CreateInstance(123); Debug.Assert(obj != null, "创建实例出错!"); //obj = type.CreateInstance("1234"); //Debug.Assert(obj != null, "创建实例出错!"); obj = type.CreateInstance(111, "aaa"); Debug.Assert(obj != null, "创建实例出错!"); XTrace.WriteLine("创建值类型实例"); type = TypeX.Create(typeof(ConsoleKeyInfo)); obj = type.CreateInstance(); Debug.Assert(obj != null, "创建值类型实例出错!"); XTrace.WriteLine("创建数组类型实例"); type = TypeX.Create(typeof(ConsoleKeyInfo[])); obj = type.CreateInstance(5); Debug.Assert(obj != null, "创建数组类型实例出错!"); #endregion #region 构造函数 ConstructorInfoX ctr = ConstructorInfoX.Create(typeof(FastTest)); obj = ctr.CreateInstance(); Debug.Assert(obj != null, "创建实例出错!"); ctr = ConstructorInfoX.Create(typeof(FastTest), new Type[] { typeof(Int32) }); obj = ctr.CreateInstance(123); Debug.Assert(obj != null, "创建实例出错!"); ctr = ConstructorInfoX.Create(typeof(FastTest), new Type[] { typeof(Int32), typeof(String) }); obj = ctr.CreateInstance(111, "aaa"); Debug.Assert(obj != null, "创建实例出错!"); #endregion #region 字段 FieldInfoX field = FieldInfoX.Create(typeof(FastTest), "_ID"); (obj as FastTest).ID = 111; Int32 v = (Int32)field.GetValue(obj); Debug.Assert(v == 111, "字段取值出错!"); field.SetValue(obj, 888); v = (Int32)field.GetValue(obj); Debug.Assert(v == 888, "字段赋值出错!"); KeyValuePair <Int32, Int32> kv = new KeyValuePair <int, int>(123456, 222); field = FieldInfoX.Create(kv.GetType(), "Key"); //field.SetValue(kv, 123456); v = (Int32)field.GetValue(kv); Debug.Assert(v == 123456, "字段取值出错!"); field = FieldInfoX.Create(typeof(FastTest), "_Name"); field.SetValue("动态赋值"); String v2 = (String)field.GetValue(); Debug.Assert(v2 == "动态赋值", "静态字段出错!"); #endregion #region 属性 PropertyInfoX p = typeof(FastTest).GetProperty("ID"); v = (Int32)p.GetValue(obj); Debug.Assert(v == 888, "属性取值出错!"); p.SetValue(obj, 999); v = (Int32)p.GetValue(obj); Debug.Assert(v == 999, "属性赋值出错!"); p = PropertyInfoX.Create(typeof(FastTest), "Name"); field.SetValue("属性动态赋值"); v2 = (String)field.GetValue(); Debug.Assert(v2 == "属性动态赋值", "静态字段出错!"); #endregion #region 方法 MethodInfoX method = MethodInfoX.Create(typeof(FastTest), "Test2"); method.Invoke(obj); method = typeof(FastTest).GetMethod("GetFullName"); Console.WriteLine(method.Invoke(null, 123, "abc")); #endregion }