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 }
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 }