Ejemplo n.º 1
0
        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
        }
Ejemplo n.º 2
0
        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
        }