Пример #1
0
        /// <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);
        }
Пример #2
0
        /// <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);
        }