public static ProxyConfiguration Create(Type type) { return configurations.GetOrAdd(type, (t) => { object[] args = t.GetCustomAttributes(typeof(ProxyAttribute), true); ProxyConfiguration config = null; if (args.Length > 0) { config = new ProxyConfiguration(args[0] as ProxyAttribute); } else { config = new ProxyConfiguration(); } foreach (var item in type.GetMembers()) { object[] memberStatus = item.GetCustomAttributes(typeof(ProxyAttribute), true); if (memberStatus.Length > 0) { config.MemberAutoProxyStatus[item.Name] = (memberStatus[0] as ProxyAttribute).DisableAutoProxy; } } if (string.IsNullOrWhiteSpace(config.DllCachedPath)) { config.DllCachedPath = AppDomain.CurrentDomain.BaseDirectory; if (!config.DllCachedPath.EndsWith("\\")) { config.DllCachedPath += "\\"; } } return config; }); }
private static void OverrideMethods(Type classToProxy, CodeTypeDeclaration proxyClassCode, ProxyConfiguration config) { foreach (MethodInfo methodInfo in FindAllMethods(classToProxy, config)) { UniqueNameHelper nameHelper = new UniqueNameHelper(); var methodCode = new CodeMemberMethod(); methodCode.Name = methodInfo.Name; if (methodInfo.ReturnType != typeof(void)) methodCode.ReturnType = GetSimpleType(methodInfo.ReturnType); var parameterList = methodInfo.GetParameters(); foreach (ParameterInfo input in parameterList) { methodCode.Parameters.Add(new CodeParameterDeclarationExpression(input.ParameterType, input.Name)); nameHelper.Add(input.Name); } CodeConditionStatement conditionalStatement = new CodeConditionStatement( new CodeVariableReferenceExpression("!this._hasInit"), new CodeSnippetStatement(string.Format("throw new ProxyException(\"You should not call a virtual method {0} in constructor.\");", methodInfo.Name))); methodCode.Statements.Add(conditionalStatement); CodeVariableDeclarationStatement v_arguments_Code = new CodeVariableDeclarationStatement("System.Object[]", nameHelper.ToUniqueName("arguments"), new CodeArrayCreateExpression("System.Object", parameterList.Length)); methodCode.Statements.Add(v_arguments_Code); for (int i = 0; i < parameterList.Length; i++) { CodeAssignStatement assignCode = new CodeAssignStatement(new CodeVariableReferenceExpression(string.Format("{1}[{0}]", i, v_arguments_Code.Name)), new CodeVariableReferenceExpression(parameterList[i].Name)); methodCode.Statements.Add(assignCode); } CodeMethodInvokeExpression invokeMethodCode; var invocation_name = nameHelper.ToUniqueName("invocation"); CodeSnippetStatement invocationCode = null; if (parameterList.Length == 0) { invocationCode = new CodeSnippetStatement(string.Format("Invocation {2} = new Invocation({1}, this._proxyBaseType.GetMethod(\"{0}\"), this);", methodInfo.Name, v_arguments_Code.Name, invocation_name)); } else { var typeArrayName = nameHelper.ToUniqueName("paramTypeList"); methodCode.Statements.Add(new CodeSnippetStatement(string.Format("Type[] {0} = new Type[{1}];", typeArrayName, parameterList.Length))); for (int i = 0; i < parameterList.Length; i++) { CodeAssignStatement assignCode = new CodeAssignStatement(new CodeVariableReferenceExpression(string.Format("{1}[{0}]", i, typeArrayName)), new CodeSnippetExpression(string.Format("typeof({0})", parameterList[i].ParameterType))); methodCode.Statements.Add(assignCode); } invocationCode = new CodeSnippetStatement(string.Format("Invocation {2} = new Invocation({1}, this._proxyBaseType.GetMethod(\"{0}\", {3}), this);", methodInfo.Name, v_arguments_Code.Name, invocation_name, typeArrayName)); } methodCode.Statements.Add(invocationCode); invokeMethodCode = new CodeMethodInvokeExpression(); invokeMethodCode.Method = new CodeMethodReferenceExpression { MethodName = "ExecuteBeforeCall" }; invokeMethodCode.Method.TargetObject = new CodeSnippetExpression("this._proxyProviderBase"); invokeMethodCode.Parameters.Add(new CodeVariableReferenceExpression(invocation_name)); methodCode.Statements.Add(invokeMethodCode); methodCode.Attributes = MemberAttributes.Override; if ((methodInfo.Attributes & MethodAttributes.Public) == MethodAttributes.Public) methodCode.Attributes |= MemberAttributes.Public; else if ((methodInfo.Attributes & MethodAttributes.Family) == MethodAttributes.Family) methodCode.Attributes |= MemberAttributes.Family; else if ((methodInfo.Attributes & MethodAttributes.FamANDAssem) == MethodAttributes.FamANDAssem) methodCode.Attributes |= MemberAttributes.FamilyAndAssembly; var temp_returnData = nameHelper.ToUniqueName("temp_returnData"); if (methodInfo.ReturnType != typeof(void)) { methodCode.Statements.Add(new CodeSnippetStatement(string.Format("var {0} = ", temp_returnData))); } invokeMethodCode = new CodeMethodInvokeExpression(); invokeMethodCode.Method = new CodeMethodReferenceExpression { MethodName = "base." + methodInfo.Name }; for (int i = 0; i < parameterList.Length; i++) { invokeMethodCode.Parameters.Add(new CodeCastExpression(parameterList[i].ParameterType, new CodeVariableReferenceExpression(string.Format("{1}[{0}]", i, v_arguments_Code.Name)))); } methodCode.Statements.Add(invokeMethodCode); if (methodInfo.ReturnType != typeof(void)) { CodeAssignStatement as11 = new CodeAssignStatement(new CodeVariableReferenceExpression(string.Format("{0}.ReturnValue", invocation_name)), new CodeVariableReferenceExpression(temp_returnData)); methodCode.Statements.Add(as11); } invokeMethodCode = new CodeMethodInvokeExpression(); invokeMethodCode.Method = new CodeMethodReferenceExpression { MethodName = "ExecuteAfterCall" }; invokeMethodCode.Method.TargetObject = new CodeSnippetExpression("this._proxyProviderBase"); invokeMethodCode.Parameters.Add(new CodeVariableReferenceExpression(invocation_name)); methodCode.Statements.Add(invokeMethodCode); if (methodInfo.ReturnType != typeof(void)) { CodeCastExpression castExpression = new CodeCastExpression(methodInfo.ReturnType, new CodeVariableReferenceExpression(string.Format("{0}.ReturnValue", invocation_name))); methodCode.Statements.Add(new CodeMethodReturnStatement(castExpression)); } proxyClassCode.Members.Add(methodCode); } }
internal static Assembly CreateLocalAssembly(Type type, ProxyConfiguration config, params Assembly[] dependAssemblies) { string localClassName = TypeInformation.GetLocalProxyClassName(type); // SituationHelper.GetLocalProxyClassName(CurrentType); var compunit = new CodeCompileUnit(); var sample = new CodeNamespace(TypeInformation.GetLocalNamespace(type)); compunit.Namespaces.Add(sample); sample.Imports.Add(new CodeNamespaceImport("System")); sample.Imports.Add(new CodeNamespaceImport("System.Linq")); sample.Imports.Add(new CodeNamespaceImport("System.Collections")); sample.Imports.Add(new CodeNamespaceImport("System.Collections.Generic")); sample.Imports.Add(new CodeNamespaceImport(typeof(RemoteRunner<>).Namespace)); sample.Imports.Add(new CodeNamespaceImport(type.Namespace)); foreach (var assembly in dependAssemblies) { if (assembly != null) { foreach (Type item in assembly.GetTypes()) { sample.Imports.Add(new CodeNamespaceImport(item.Namespace)); } } } //定义一个名为DemoClass的类 // compunit.ReferencedAssemblies.Add(currentType.Assembly.FullName); var wrapProxyClass = new CodeTypeDeclaration(localClassName); wrapProxyClass.BaseTypes.Add(type); wrapProxyClass.CustomAttributes.Add(new CodeAttributeDeclaration("Serializable")); sample.Types.Add(wrapProxyClass); var providerBaseField = new CodeMemberField(typeof(ProxyProviderBase), "_proxyProviderBase"); wrapProxyClass.Members.Add(providerBaseField); var baseTypeField = new CodeMemberField(typeof(Type), "_proxyBaseType"); wrapProxyClass.Members.Add(baseTypeField); var constructor = new CodeConstructor(); constructor.Attributes = MemberAttributes.Public; constructor.Parameters.Add(new CodeParameterDeclarationExpression(typeof(ProxyProviderBase), "_proxyProviderBase")); constructor.Statements.Add(new CodeAssignStatement(new CodeVariableReferenceExpression("this._proxyProviderBase"), new CodeVariableReferenceExpression("_proxyProviderBase"))); constructor.Statements.Add(new CodeVariableReferenceExpression("this._proxyBaseType = this.GetType().BaseType;")); wrapProxyClass.Members.Add(constructor); foreach (MethodInfo item in type.GetMethods()) { if (item.IsPublic && !item.IsStatic && item.IsVirtual && !type.BaseType.GetMethods().Any(p => p.Name == item.Name)) { var method = new CodeMemberMethod(); method.Name = item.Name; if (item.ReturnType != typeof(void)) method.ReturnType = GetSimpleType(item.ReturnType); //method.ReturnType = new CodeTypeReference(item.ReturnType); foreach (ParameterInfo input in item.GetParameters()) { method.Parameters.Add(new CodeParameterDeclarationExpression(input.ParameterType, input.Name)); } method.Attributes = MemberAttributes.Override | MemberAttributes.Public; if (item.ReturnType != typeof(void)) { method.Statements.Add(new CodeSnippetStatement("var temp_returnData_1024=")); } var cs = new CodeMethodInvokeExpression(); cs.Method = new CodeMethodReferenceExpression { MethodName = "RemoteRunner<" + type.Namespace + "." + type.Name + ">.RemoteT." + item.Name }; foreach (ParameterInfo input in item.GetParameters()) { //Type t = input.ParameterType; //Situation situation = SituationHelper.GetSituation(t); cs.Parameters.Add(new CodeSnippetExpression(input.Name)); // cs.Parameters.Add(new CodeSnippetExpression(SituationHelper.GetExpression(t, input.Name))); } method.Statements.Add(cs); if (item.ReturnType != typeof(void)) { method.Statements.Add(new CodeSnippetStatement("return temp_returnData_1024;")); } wrapProxyClass.Members.Add(method); } } var cprovider = new CSharpCodeProvider(); var fileContent = new StringBuilder(); using (var sw = new StringWriter(fileContent)) { cprovider.GenerateCodeFromCompileUnit(compunit, sw, new CodeGeneratorOptions()); } var cp = new CompilerParameters(); cp.ReferencedAssemblies.Add("System.dll"); cp.ReferencedAssemblies.Add("System.Core.dll"); //cp.ReferencedAssemblies.Add(config.DllCachedPath + Path.GetFileName(typeof(ServiceContext).Assembly.Location)); cp.ReferencedAssemblies.Add(config.DllCachedPath + Path.GetFileName(typeof(RemoteRunner<>).Assembly.Location)); cp.ReferencedAssemblies.Add(config.DllCachedPath + Path.GetFileName(type.Assembly.Location)); //cp.ReferencedAssemblies.Add(DllCachePath + Path.GetFileName(InterfaceAssembly.Location)); //RefComponents(cp, EntityTypes); //foreach (string file in Directory.GetFiles(config.DllCachedPath, "*.dll")) //{ // if (file.ToUpper().StartsWith("Clover.")) // continue; // cp.ReferencedAssemblies.Add(file); //} foreach (var assembly in dependAssemblies) { if (assembly != null) { cp.ReferencedAssemblies.Add(assembly.Location); } } cp.OutputAssembly = config.DllCachedPath + type.FullName + ".Local.dll"; cp.GenerateInMemory = false; cp.IncludeDebugInformation = true; cp.GenerateExecutable = false; //生成EXE,不是DLL cp.WarningLevel = 4; cp.TreatWarningsAsErrors = false; string filePath = config.DllCachedPath + @"Class\" + type.Namespace + "." + type.Name + ".Local.cs"; if (!Directory.Exists(Path.GetDirectoryName(filePath))) Directory.CreateDirectory(Path.GetDirectoryName(filePath)); File.WriteAllText(filePath, fileContent.ToString()); CompilerResults cr = cprovider.CompileAssemblyFromFile(cp, filePath); String outputMessage = ""; foreach (string item in cr.Output) { outputMessage += item + Environment.NewLine; } if (cr.Errors.Count > 0) { throw new ProxyException("Compile local proxy class error:" + Environment.NewLine + outputMessage); } return cr.CompiledAssembly; }
private static List<MethodInfo> FindAllMethods(Type type, ProxyConfiguration config) { if (config.DisableAutoProxy) return new List<MethodInfo>(); var methodInfoList = type.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly).Where(p => p.IsVirtual && !p.IsSpecialName); var resultList = new List<MethodInfo>(); foreach (var methodInfo in methodInfoList) { bool status; if (config.MemberAutoProxyStatus.TryGetValue(methodInfo.Name, out status)) { if (status) resultList.Add(methodInfo); } else { resultList.Add(methodInfo); } } return resultList; }
private static List<PropertyInfo> FindAllProperties(Type type, ProxyConfiguration config) { if (config.DisableAutoProxy) return new List<PropertyInfo>(); var propertyInfoList = type.GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly).Where(p => p.GetGetMethod().IsVirtual).ToList(); var resultList = new List<PropertyInfo>(); foreach (var propertyInfo in propertyInfoList) { bool status; if (config.MemberAutoProxyStatus.TryGetValue(propertyInfo.Name, out status)) { if (status) { resultList.Add(propertyInfo); } } else { resultList.Add(propertyInfo); } } return resultList; }
private static void OverrideProperties(Type currentType, CodeTypeDeclaration wrapProxyClass, ProxyConfiguration config) { foreach (PropertyInfo pInfo in FindAllProperties(currentType, config)) { var getinvocationCode = new CodeSnippetStatement(string.Format("Invocation getinvocation = new Invocation(new object[0], this._proxyBaseType.GetProperty(\"{0}\").GetGetMethod(), this);", pInfo.Name)); var setinvocationCode = new CodeSnippetStatement(string.Format("Invocation setinvocation = new Invocation(new object[]{{value}}, this._proxyBaseType.GetProperty(\"{0}\").GetSetMethod(), this);", pInfo.Name)); var propertyCode = new CodeMemberProperty(); propertyCode.Name = pInfo.Name; propertyCode.Type = GetSimpleType(pInfo.PropertyType); propertyCode.Attributes = MemberAttributes.Override | MemberAttributes.Public; CodeConditionStatement conditionalStatement = new CodeConditionStatement( new CodeVariableReferenceExpression("!this._hasInit"), new CodeSnippetStatement(string.Format("base.{0} = value;return;", pInfo.Name))); //propertyCode.GetStatements.Add( propertyCode.GetStatements.Add(getinvocationCode); propertyCode.SetStatements.Add(conditionalStatement); propertyCode.SetStatements.Add(setinvocationCode); propertyCode.GetStatements.Add(new CodeSnippetStatement("this._proxyProviderBase.ExecuteBeforeCall(getinvocation);")); propertyCode.SetStatements.Add(new CodeSnippetStatement("this._proxyProviderBase.ExecuteBeforeCall(setinvocation);")); propertyCode.GetStatements.Add(new CodeSnippetStatement(string.Format("var temp_returnData_1024 = base.{0};\r\ngetinvocation.ReturnValue = temp_returnData_1024;", pInfo.Name))); propertyCode.SetStatements.Add(new CodeSnippetStatement(string.Format("base.{0} = value;", pInfo.Name))); propertyCode.GetStatements.Add(new CodeSnippetStatement("this._proxyProviderBase.ExecuteAfterCall(getinvocation);")); propertyCode.SetStatements.Add(new CodeSnippetStatement("this._proxyProviderBase.ExecuteAfterCall(setinvocation);")); propertyCode.GetStatements.Add(new CodeSnippetStatement("var result = ")); CodeCastExpression castExpression = new CodeCastExpression(pInfo.PropertyType, new CodeVariableReferenceExpression("getinvocation.ReturnValue")); propertyCode.GetStatements.Add(castExpression); propertyCode.GetStatements.Add(new CodeSnippetStatement("return result;")); wrapProxyClass.Members.Add(propertyCode); } }
private static CompilerParameters CreateCompilerParameters(Type proxyedType, ProxyConfiguration config) { var compilerParameters = new CompilerParameters(); compilerParameters.ReferencedAssemblies.Add("System.dll"); compilerParameters.ReferencedAssemblies.Add("System.Core.dll"); compilerParameters.ReferencedAssemblies.Add(config.DllCachedPath + Path.GetFileName(typeof(RemoteRunner<>).Assembly.Location)); compilerParameters.ReferencedAssemblies.Add(config.DllCachedPath + Path.GetFileName(proxyedType.Assembly.Location)); compilerParameters.OutputAssembly = config.DllCachedPath + proxyedType.FullName + ".Local.dll"; compilerParameters.GenerateInMemory = false; compilerParameters.IncludeDebugInformation = true; compilerParameters.GenerateExecutable = false; //生成EXE,不是DLL compilerParameters.WarningLevel = 4; compilerParameters.TreatWarningsAsErrors = false; return compilerParameters; }
internal static Assembly CreateLocalClassAssembly(Type type, ProxyConfiguration config) { string localClassName = TypeInformation.GetLocalProxyClassName(type); var codeUnit = new CodeCompileUnit(); var codeNamespace = CreateNSAndImportInitNS(type, codeUnit); var wrapProxyClass = new CodeTypeDeclaration(localClassName); wrapProxyClass.BaseTypes.Add(type); if (HasMarkSerializable(type)) wrapProxyClass.CustomAttributes.Add(new CodeAttributeDeclaration("Serializable")); codeNamespace.Types.Add(wrapProxyClass); var providerBaseField = new CodeMemberField(typeof(ProxyProviderBase), "_proxyProviderBase"); wrapProxyClass.Members.Add(providerBaseField); var baseTypeField = new CodeMemberField(typeof(Type), "_proxyBaseType"); wrapProxyClass.Members.Add(baseTypeField); wrapProxyClass.Members.Add(new CodeMemberField(typeof(bool), "_hasInit")); var constructor = new CodeConstructor(); constructor.Attributes = MemberAttributes.Public; constructor.Parameters.Add(new CodeParameterDeclarationExpression(typeof(ProxyProviderBase), "_proxyProviderBase")); constructor.Statements.Add(new CodeAssignStatement(new CodeVariableReferenceExpression("this._proxyProviderBase"), new CodeVariableReferenceExpression("_proxyProviderBase"))); constructor.Statements.Add(new CodeVariableReferenceExpression("this._proxyBaseType = this.GetType().BaseType;")); constructor.Statements.Add(new CodeVariableReferenceExpression("this._hasInit = true;")); wrapProxyClass.Members.Add(constructor); OverrideMethods(type, wrapProxyClass, config); OverrideProperties(type, wrapProxyClass, config); var cprovider = new CSharpCodeProvider(); var fileContent = new StringBuilder(); using (var sw = new StringWriter(fileContent)) { cprovider.GenerateCodeFromCompileUnit(codeUnit, sw, new CodeGeneratorOptions()); } var compilerParameters = CreateCompilerParameters(type, config); string filePath = config.DllCachedPath + @"Class\" + type.Namespace + "." + type.Name + ".Local.cs"; if (!Directory.Exists(Path.GetDirectoryName(filePath))) Directory.CreateDirectory(Path.GetDirectoryName(filePath)); File.WriteAllText(filePath, fileContent.ToString()); CompilerResults cr = cprovider.CompileAssemblyFromFile(compilerParameters, filePath); String outputMessage = ""; foreach (string item in cr.Output) { outputMessage += item + Environment.NewLine; } if (cr.Errors.Count > 0) { throw new ProxyException("compile local proxy class error:" + Environment.NewLine + outputMessage); } return cr.CompiledAssembly; }
internal static Assembly CreateRemoteAssembly(Type type, ProxyConfiguration config, params Assembly[] dependAssemblies) { string remoteProxyClassName = TypeInformation.GetRemoteProxyClassName(type); var compunit = new CodeCompileUnit(); var sample = new CodeNamespace(TypeInformation.GetRemoteNamespace(type)); compunit.Namespaces.Add(sample); sample.Imports.Add(new CodeNamespaceImport("System")); sample.Imports.Add(new CodeNamespaceImport("System.Linq")); sample.Imports.Add(new CodeNamespaceImport("System.Collections")); sample.Imports.Add(new CodeNamespaceImport("System.Collections.Generic")); sample.Imports.Add(new CodeNamespaceImport("System.Security.Principal")); sample.Imports.Add(new CodeNamespaceImport("System.Threading")); //sample.Imports.Add(new CodeNamespaceImport(typeof(ServiceContext).Namespace)); sample.Imports.Add(new CodeNamespaceImport(typeof(RemoteRunner<>).Namespace)); foreach (var assembly in dependAssemblies) { if (assembly != null) { foreach (Type item in assembly.GetTypes()) { sample.Imports.Add(new CodeNamespaceImport(item.Namespace)); } } } var wrapProxyClass = new CodeTypeDeclaration(remoteProxyClassName); wrapProxyClass.BaseTypes.Add(type); wrapProxyClass.CustomAttributes.Add(new CodeAttributeDeclaration("Serializable")); sample.Types.Add(wrapProxyClass); var constructor = new CodeConstructor(); constructor.Attributes = MemberAttributes.Public; wrapProxyClass.Members.Add(constructor); foreach (MethodInfo item in type.GetMethods()) { if (item.IsPublic && !item.IsStatic && item.IsVirtual && !type.BaseType.GetMethods().Any(p => p.Name == item.Name)) { var method = new CodeMemberMethod(); method.Name = item.Name; // method.Statements.Add( if (item.ReturnType != typeof(void)) method.ReturnType = GetSimpleType(item.ReturnType); // method.ReturnType = new CodeTypeReference(item.ReturnType); foreach (ParameterInfo input in item.GetParameters()) { method.Parameters.Add(new CodeParameterDeclarationExpression(input.ParameterType, input.Name)); } //write line // method.Statements.Add(new CodeSnippetStatement(typeof(ServiceContext).Namespace + "." + typeof(ServiceContext).Name + ".SetThreadPrincipal();")); if (true) //if enable before call { // CodeMemberMethod beforeCallMethod = new CodeMemberMethod(); //beforeCallMethod.Parameters=new CodeParameterDeclarationExpression(typeof(object[]), // method.Statements.Add(new CodeSnippetStatement("EventMonitor.BeforeCall(null);")); } method.Statements.Add(new CodeSnippetStatement( @" WindowsIdentity WindowsIdentity_1024 = WindowsIdentity.GetCurrent(); try { ")); method.Attributes = MemberAttributes.Override | MemberAttributes.Public; if (item.ReturnType != typeof(void)) { method.Statements.Add(new CodeSnippetStatement("var temp_returnData_1024=")); } var cs = new CodeMethodInvokeExpression(); cs.Method = new CodeMethodReferenceExpression { MethodName = "base." + item.Name }; foreach (ParameterInfo input in item.GetParameters()) { cs.Parameters.Add(new CodeSnippetExpression(input.Name)); } method.Statements.Add(cs); if (item.ReturnType != typeof(void)) { method.Statements.Add(new CodeSnippetStatement("return temp_returnData_1024;")); // Type type = item.ReturnType; // Situation situation = SituationHelper.GetSituation(item.ReturnType); // switch (situation) // { // case Situation.SerializableNullableT: // case Situation.SerializableArray: // case Situation.SerializableDirtionary: // case Situation.Serializable: // { // method.Statements.Add(new CodeSnippetStatement("return temp_returnData_1024;")); // break; // } // case Situation.UnSerializable: // { // method.Statements.Add(new CodeSnippetStatement("return new Serializable_" + type.Name + "(temp_returnData_1024);")); // break; // } // case Situation.Array: // { // method.Statements.Add(new CodeSnippetStatement(string.Format(@" //if(temp_returnData_1024==null) return null; //return temp_returnData_1024.ToList().ConvertAll<{0}>(p => p==null ? null: new Serializable_{0}(p)).ToArray();", SituationHelper.GetInternalTypeFormArray(type)[0].Name))); // break; // } // case Situation.IEnumableT: // { // method.Statements.Add(new CodeSnippetStatement(string.Format(@" //if(temp_returnData_1024==null) return null; //return temp_returnData_1024.ToList().ConvertAll<{0}>(p => p==null ? null: new Serializable_{0}(p));", SituationHelper.GetInternalTypeFormArray(type)[0].Name))); // break; // } // case Situation.Dictionary: // { // Type[] types = SituationHelper.GetInternalTypeFormArray(type); // method.Statements.Add(new CodeSnippetStatement(string.Format(@" //if(temp_returnData_1024==null) return null; //return {0} ;", SituationHelper.GetExpression(type, "temp_returnData_1024")))); // break; // } // } } method.Statements.Add(new CodeSnippetStatement( @" } catch (Exception)// ex_1024) { // Logger.Current.WriteEntry(ex_1024); // if (!(ex_1024.GetType().IsSerializable)) // { // throw ErrorService.CreateException<InvalidOperationException>(ErrorCode.InternalCompontentException, ex_1024.GetType().Name, ex_1024.Message, ex_1024.StackTrace); // } throw; } finally { if(WindowsIdentity_1024!=null) WindowsIdentity_1024.Impersonate(); //EventMonitor.AfterCall(); } ")); wrapProxyClass.Members.Add(method); } } var cprovider = new CSharpCodeProvider(); var fileContent = new StringBuilder(); using (var sw = new StringWriter(fileContent)) { cprovider.GenerateCodeFromCompileUnit(compunit, sw, new CodeGeneratorOptions()); } var cp = new CompilerParameters(); cp.ReferencedAssemblies.Add("System.dll"); cp.ReferencedAssemblies.Add("System.Core.dll"); cp.ReferencedAssemblies.Add(config.DllCachedPath + Path.GetFileName(typeof(RemoteRunner<>).Assembly.Location)); cp.ReferencedAssemblies.Add(config.DllCachedPath + Path.GetFileName(type.Assembly.Location)); //cp.ReferencedAssemblies.Add(config.DllCachedPath + Path.GetFileName(InterfaceAssembly.Location)); //RefComponents(cp, EntityTypes); foreach (var assembly in dependAssemblies) { if (assembly != null) cp.ReferencedAssemblies.Add(assembly.Location); } //foreach (string file in Directory.GetFiles(config.DllCachedPath, "*.dll")) //{ // if (file.ToUpper().StartsWith("Clover.")) // continue; // cp.ReferencedAssemblies.Add(file); //} cp.OutputAssembly = config.DllCachedPath + type.FullName + ".Remote.dll"; cp.GenerateInMemory = false; cp.IncludeDebugInformation = true; cp.GenerateExecutable = false; cp.WarningLevel = 4; cp.TreatWarningsAsErrors = false; string filePath = config.DllCachedPath + @"Class\" + type.Namespace + "." + type.Name + ".Remote.cs"; if (!Directory.Exists(Path.GetDirectoryName(filePath))) Directory.CreateDirectory(Path.GetDirectoryName(filePath)); File.WriteAllText(filePath, fileContent.ToString()); CompilerResults cr = cprovider.CompileAssemblyFromFile(cp, filePath); String outputMessage = ""; foreach (string item in cr.Output) { outputMessage += item + Environment.NewLine; } if (cr.Errors.Count > 0) { throw new ProxyException("compile remote proxy class error:" + Environment.NewLine + outputMessage); } return cr.CompiledAssembly; }
internal static Assembly CreateEntityAssembly(Type type, ProxyConfiguration config, params Assembly[] dependAssemblies) { var compunit = new CodeCompileUnit(); var sample = new CodeNamespace(TypeInformation.GetEntityNamespace(type)); compunit.Namespaces.Add(sample); sample.Imports.Add(new CodeNamespaceImport("System")); sample.Imports.Add(new CodeNamespaceImport("System.Linq")); sample.Imports.Add(new CodeNamespaceImport("System.Collections")); sample.Imports.Add(new CodeNamespaceImport("System.Collections.Generic")); sample.Imports.Add(new CodeNamespaceImport(typeof(RemoteRunner<>).Namespace)); sample.Imports.Add(new CodeNamespaceImport(type.Namespace)); foreach (var assembly in dependAssemblies) { foreach (Type item in assembly.GetTypes()) { sample.Imports.Add(new CodeNamespaceImport(item.Namespace)); } } List<Type> entityTypes = new List<Type>(); foreach (MethodInfo item in type.GetMethods()) { if (item.IsPublic && !item.IsStatic && item.IsVirtual && !type.BaseType.GetMethods().Any(p => p.Name == item.Name)) { foreach (ParameterInfo input in item.GetParameters()) { DelareSerializableParameter(entityTypes, input.ParameterType, sample); } if (item.ReturnType != typeof(void)) { DelareSerializableParameter(entityTypes, item.ReturnType, sample); } } } if (entityTypes.Count == 0) return null; var cprovider = new CSharpCodeProvider(); var fileContent = new StringBuilder(); using (var sw = new StringWriter(fileContent)) { cprovider.GenerateCodeFromCompileUnit(compunit, sw, new CodeGeneratorOptions()); } var cp = new CompilerParameters(); cp.ReferencedAssemblies.Add("System.dll"); cp.ReferencedAssemblies.Add("System.Core.dll"); cp.ReferencedAssemblies.Add(config.DllCachedPath + Path.GetFileName(typeof(RemoteRunner<>).Assembly.Location)); cp.ReferencedAssemblies.Add(config.DllCachedPath + Path.GetFileName(type.Assembly.Location)); cp.OutputAssembly = config.DllCachedPath + type.FullName + ".Entity.dll"; cp.GenerateInMemory = false; cp.IncludeDebugInformation = true; cp.GenerateExecutable = false; //生成EXE,不是DLL cp.WarningLevel = 4; cp.TreatWarningsAsErrors = false; CompilerResults cr = null; string filePath = config.DllCachedPath + @"Class\" + type.FullName + ".Entity.cs"; if (!Directory.Exists(Path.GetDirectoryName(filePath))) Directory.CreateDirectory(Path.GetDirectoryName(filePath)); File.WriteAllText(filePath, fileContent.ToString()); cr = cprovider.CompileAssemblyFromFile(cp, filePath); String outputMessage = ""; foreach (string item in cr.Output) { outputMessage += item + Environment.NewLine; } if (cr.Errors.Count > 0) { throw new ProxyException("Compile entity proxy class error:" + Environment.NewLine + outputMessage); } //AppDomain.CurrentDomain.Load(cr.CompiledAssembly); return cr.CompiledAssembly; }