/// <summary> /// 生成并编译指定类型的代理类型 /// </summary> /// <param name="entityTypes"></param> /// <param name="dllFilePath"></param> /// <returns></returns> internal static List <EntityCompileResult> Compile(Type[] entityTypes, string dllFilePath) { if (entityTypes == null) { throw new ArgumentNullException(nameof(entityTypes)); } if (entityTypes.Length == 0) { return(new List <EntityCompileResult>(0)); } StringBuilder sb = new StringBuilder(); sb.AppendLine(EntityGenerator.UsingCodeBlock); List <EntityCompileResult> result = new List <EntityCompileResult>(entityTypes.Length); for (int i = 0; i < entityTypes.Length; i++) { EntityGenerator g = new EntityGenerator(); string code = g.GetCode(entityTypes[i]); sb.AppendLine(code); EntityCompileResult cr = new EntityCompileResult(); cr.ProxyName = g.NameSpace + "." + g.ProxyClassName; cr.LoaderName = g.NameSpace + "." + g.DataLoaderClassName; result.Add(cr); } string tempOutPath = ConfigurationManager.AppSettings["ClownFish.Data:ProxyBuilder.TempOutPath"]; // 编译有可能会抛出异常,这里不处理。 Assembly asm = CompilerHelper.CompileCode(sb.ToString(), dllFilePath, tempOutPath); foreach (var cr in result) { cr.ProxyType = asm.GetType(cr.ProxyName); cr.LoaderType = asm.GetType(cr.LoaderName); cr.LoaderInstnace = cr.LoaderType.FastNew(); // 创建加载器的实例,供后面注册使用 } return(result); }
/// <summary> /// 加载所有已存在的实体代理对应的实体类型。 /// 说明:已经存在的代理类型是用工具提前生成好的。 /// </summary> /// <returns></returns> private static List <EntityCompileResult> SearchExistEntityCompileResult() { // 工具生成的程序集一定会使用EntityProxyAssemblyAttribute,所以用它做过滤 List <Assembly> proxyAsmList = ClownFish.Base.Reflection.ReflectionExtensions.GetAssemblyList <EntityProxyAssemblyAttribute>(); List <EntityCompileResult> list = new List <EntityCompileResult>(1024); foreach (Assembly asm in proxyAsmList) { foreach (Type t in asm.GetPublicTypes()) { // 工具会为每个实体类型生成二个辅助类型:XxxxxProxy, XxxxxLoader // XxxxxLoader,实体加载器类型,用于从数据结果中加载实体列表 // XxxxxProxy,实体代理类型,用于跟踪实体数据成员的修改情况,并用于生成INSERT/UPDATE/DELETE语句 // 如果实体是密封类型,将不会生成实体代理类,但是实体加载器类型一定会生成 // 所以,在查找时,先找【实体加载器类型】,并根据EntityAdditionAttribute来查找配对的【实体代理类型】 // 【实体加载器类型】的样例代码请参考 \test\ClownFish.Data.UnitTest\AutoCode1.cs if (t.BaseType.IsGenericType && t.BaseType.GetGenericTypeDefinition() == typeof(BaseDataLoader <>)) { EntityCompileResult cr = new EntityCompileResult(); cr.EntityType = t.BaseType.GetGenericArguments()[0]; cr.LoaderType = t; cr.LoaderInstnace = cr.LoaderType.FastNew(); // 创建加载器的实例,供后面注册使用 // 使用.NET原生版本GetCustomAttribute,因为不需要缓存,请不要修改成 GetMyAttribute<>() EntityAdditionAttribute a = t.GetCustomAttribute <EntityAdditionAttribute>(); if (a != null) // 允许没有代理类(实体就是封闭类型) { cr.ProxyType = a.ProxyType; } list.Add(cr); } } } return(list); }