Пример #1
0
 /// <summary>
 /// 获取当前的实体类型组合
 /// </summary>
 /// <returns></returns>
 protected EntityMatrix GetConventionItem()
 {
     if (this._cacheConvention == null)
     {
         this._cacheConvention = GetConventionItemCore();
     }
     return(this._cacheConvention);
 }
Пример #2
0
 private static void ProcessTypesInPlugin(IPlugin plugin)
 {
     foreach (var type in plugin.Assembly.GetTypes())
     {
         ServiceLocator.TryAddService(type);
         EntityMatrix.TryAddRepository(type);
         DataProviderComposer.TryAddDataProvider(type);
     }
 }
Пример #3
0
        /// <summary>
        /// 查询实体类型组合
        /// </summary>
        /// <returns></returns>
        private EntityMatrix GetConventionItemCore()
        {
            //if (this.RealEntityType != null)
            //{
            //    return EntityMatrix.FindByEntity(this.RealEntityType);
            //}

            //默认使用约定查询出实体类型组合
            return(EntityMatrix.FindByRepository(this.GetType()));
        }
Пример #4
0
        /// <summary>
        /// 为实体类型生成一个默认的实体类。
        /// </summary>
        /// <param name="entityType"></param>
        /// <returns></returns>
        private Type GenerateDefaultRepositoryType(Type entityType)
        {
            var baseType = entityType.BaseType;

            //找到继承链条上,最近的一个非泛型父类的仓库类型
            Type baseRepositoryType = null;

            while (baseType != typeof(Entity))
            {
                if (baseType == null)
                {
                    throw new InvalidProgramException("此类并没有继承 Entity 类,不能创建 Repository。");
                }
                if (!baseType.IsGenericType)
                {
                    //不需要为基类创建仓库,这是因为基类声明的仓库类型可能是抽象类型。
                    //var repository = this.FindWithoutLock(baseType);
                    //baseRepositoryType = repository.GetType();

                    var convention = EntityMatrix.FindByEntity(baseType);
                    baseRepositoryType = convention.RepositoryType;
                    break;
                }

                baseType = baseType.BaseType;
            }

            //如果没有,则直接从DefaultEntityRepository上继承。
            if (baseRepositoryType == null)
            {
                baseRepositoryType = typeof(EntityRepository);
            }

            //查找这个类型
            var module    = EmitContext.Instance.GetDynamicModule();
            var className = EntityMatrix.RepositoryFullName(entityType);

            //尝试查找这个类型
            var exsitType = module.GetType(className, false);

            if (exsitType != null)
            {
                return(exsitType);
            }

            //构造一个新的类型。
            var newType = module.DefineType(
                className,
                TypeAttributes.Public | TypeAttributes.Class,
                baseRepositoryType
                );

            return(newType.CreateType());
        }
Пример #5
0
        /// <summary>
        /// 尝试找到这个实体列表对应的仓库类。
        ///
        /// 没有标记 RootEntity/ChildEntity 的类型是没有仓库类的,例如所有的条件类型。
        /// </summary>
        /// <returns></returns>
        public IRepository FindRepository()
        {
            if (!this._repositoryLoaded)
            {
                var entityType = EntityMatrix.FindByList(this.GetType()).EntityType;
                this._repository = RepositoryFactoryHost.Factory.FindByEntity(entityType);

                this._repositoryLoaded = true;
            }

            return(this._repository);
        }
Пример #6
0
        internal static void TryAddRepository(Type repositoryType)
        {
            var attri = repositoryType.GetSingleAttribute <RepositoryForAttribute>();

            if (attri != null)
            {
                Type entityType = attri.EntityType;
                var  listType   = Convention_ListForEntity(entityType);
                var  item       = new EntityMatrix(entityType, listType, repositoryType);
                Add(item);
            }
        }
Пример #7
0
        private void OnMetaCompiled(object sender, EventArgs e)
        {
            var plugins = RafyEnvironment.AllPlugins;

            foreach (var plugin in plugins)
            {
                foreach (var type in plugin.Assembly.GetTypes())
                {
                    ServiceLocator.TryAddService(type);
                    EntityMatrix.TryAddRepository(type);
                    DataProviderComposer.TryAddDataProvider(type);
                }
            }
        }
Пример #8
0
        private static EntityMatrix FastFindByListType(Type listType)
        {
            try
            {
                _rwLock.EnterReadLock();

                EntityMatrix item = null;
                _listIndex.TryGetValue(listType, out item);
                return(item);
            }
            finally
            {
                _rwLock.ExitReadLock();
            }
        }
Пример #9
0
        private static EntityMatrix FastFindByRepositoryType(Type repositoryType)
        {
            try
            {
                _rwLock.EnterReadLock();

                EntityMatrix item = null;
                _repositoryIndex.TryGetValue(repositoryType, out item);
                return(item);
            }
            finally
            {
                _rwLock.ExitReadLock();
            }
        }
Пример #10
0
        /// <summary>
        /// LiteDataTable 类型的扩展方法,实现 LiteDataTable 类型到 EntityList 类型的转换。
        /// </summary>
        /// <typeparam name="TEntityList">The type of the entity list.</typeparam>
        /// <param name="table">The table.</param>
        /// <param name="columnMapToProperty">
        /// 此参数表示表格中的列名是否直接映射实体的属性名。
        /// true:表格列名就是属性名。
        /// false:表格中列名映射的是实体对应的数据库表的列名,而非属性名。
        /// 默认为 true。
        /// </param>
        /// <returns></returns>
        public static TEntityList ToEntityList <TEntityList>(this LiteDataTable table, bool columnMapToProperty = true) where TEntityList : EntityList
        {
            //属性和对应列的键值对集合,为后面填充实体用。
            var propertyMappings = new List <PropertyToColumnMapping>(10);
            var entityMatrix     = EntityMatrix.FindByList(typeof(TEntityList));
            var repo             = RepositoryFacade.Find(entityMatrix.EntityType);
            var properties       = repo.EntityMeta.EntityProperties;
            var columns          = table.Columns;

            for (int i = 0, c = properties.Count; i < c; i++)
            {
                var propertyMeta = properties[i];
                var property     = propertyMeta.ManagedProperty;
                if (!property.IsReadOnly)
                {
                    //这个位置是针对于时间戳的那几个字段 columnMeta 不为空 ,但是映射到数据库的 columnName 这个属性是空的。
                    //还有种情况是 columnMeta 为空,比如当对应的属性为 treeIndex。
                    var columnName = property.Name;
                    if (!columnMapToProperty)
                    {
                        var columnMeta = propertyMeta.ColumnMeta;
                        columnName = columnMeta == null ? propertyMeta.Name : columnMeta.ColumnName;
                    }

                    for (int columnIndex = 0, c2 = columns.Count; columnIndex < c2; columnIndex++)
                    {
                        var column = columns[columnIndex];
                        if (column.ColumnName.EqualsIgnoreCase(columnName))
                        {
                            propertyMappings.Add(new PropertyToColumnMapping
                            {
                                Property    = property,
                                ColumnName  = columnName,
                                ColumnIndex = columnIndex
                            });

                            break;
                        }
                    }
                }
            }

            return(ConvertEntitiesIntoList(table, repo, propertyMappings, columnMapToProperty) as TEntityList);
        }
Пример #11
0
        /// <summary>
        /// 创建一个实体类型的仓库。
        /// </summary>
        /// <param name="entityType"></param>
        /// <returns></returns>
        private EntityRepository DoCreate(Type entityType)
        {
            //先尝试在约定中寻找实体类型自己定义的仓库类型。
            var metrix   = EntityMatrix.FindByEntity(entityType);
            var repoType = metrix.RepositoryType;

            if (repoType != null)
            {
                if (repoType.IsAbstract)
                {
                    throw new InvalidProgramException(repoType.FullName + " 仓库类型是抽象的,无法创建。");
                }

                var repo = this.CreateInstanceProxy(repoType) as EntityRepository;
                //EntityRepository repo;
                //if (RafyEnvironment.Location.ConnectDataDirectly || repoType.IsSubclassOf(typeof(MemoryEntityRepository)))
                //{
                //    repo = Activator.CreateInstance(repoType, true) as EntityRepository;

                //    if (repo == null)
                //    {
                //        throw new InvalidProgramException("{0} 类型必须继承自 EntityRepository 类型。".FormatArgs(repoType));
                //    }
                //}
                //else
                //{
                //    repo = _proxyGenerator.CreateClassProxy(repoType, RepositoryInterceptor.Instance) as EntityRepository;
                //}

                var repoDataProvider = DataProviderComposer.CreateDataProvider(repoType);

                repo.InitDataProvider(repoDataProvider);
                repoDataProvider.InitRepository(repo);

                return(repo);
            }

            throw new InvalidProgramException(entityType.FullName + " 类型没有对应的仓库,创建仓库失败!");

            //实体类必须编写对应的 EntityRepository 类型,不再支持生成默认类型。
            ////如果上面在约定中没有找到,则直接生成一个默认的实体仓库。
            //return this.CreateDefaultRepository(entityType);
        }
Пример #12
0
        /// <summary>
        /// 通过仓库类找到约定项
        /// </summary>
        /// <param name="repositoryType"></param>
        /// <returns></returns>
        public static EntityMatrix FindByRepository(Type repositoryType)
        {
            if (repositoryType == null)
            {
                return(null);
            }

            var item = FastFindByRepositoryType(repositoryType);

            if (item == null)
            {
                var entityType = Convention_EntityForRepository(repositoryType);
                var listType   = Convention_ListForEntity(entityType);
                item = new EntityMatrix(entityType, listType, repositoryType);
                Add(item);
            }

            return(item);
        }
Пример #13
0
        /// <summary>
        /// 通过实体类找到约定项
        /// </summary>
        /// <param name="entityType"></param>
        /// <returns></returns>
        public static EntityMatrix FindByEntity(Type entityType)
        {
            if (entityType == null)
            {
                throw new ArgumentNullException("entityType");
            }

            var item = FastFindByEntityType(entityType);

            if (item == null)
            {
                var listType = Convention_ListForEntity(entityType);
                var rpType   = Convention_RepositoryForEntity(entityType);
                item = new EntityMatrix(entityType, listType, rpType);
                Add(item);
            }

            return(item);
        }
Пример #14
0
        private static void Add(EntityMatrix item)
        {
            try
            {
                _rwLock.EnterReadLock();

                if (!_entityIndex.ContainsKey(item.EntityType))
                {
                    _entityIndex.Add(item.EntityType, item);
                    if (item.ListType != null)
                    {
                        _listIndex.Add(item.ListType, item);
                    }
                    if (item.RepositoryType != null)
                    {
                        _repositoryIndex.Add(item.RepositoryType, item);
                    }
                }
            }
            finally
            {
                _rwLock.ExitReadLock();
            }
        }
Пример #15
0
        /// <summary>
        /// 创建一个实体类型的仓库。
        /// </summary>
        /// <param name="entityType"></param>
        /// <returns></returns>
        private EntityRepository DoCreate(Type entityType)
        {
            //先尝试在约定中寻找实体类型自己定义的仓库类型。
            var metrix   = EntityMatrix.FindByEntity(entityType);
            var repoType = metrix.RepositoryType;

            if (repoType != null)
            {
                if (repoType.IsAbstract)
                {
                    throw new InvalidProgramException(repoType.FullName + " 仓库类型是抽象的,无法创建。");
                }

                var repo = Activator.CreateInstance(repoType, true) as EntityRepository;
                if (repo == null)
                {
                    throw new InvalidProgramException(string.Format(
                                                          "{0} 类型必须继承自 EntityRepository 类型。",
                                                          repoType
                                                          ));
                }

                var repoDataProvider = DataProviderComposer.CreateDataProvider(repoType);

                repo.InitDataProvider(repoDataProvider);
                repoDataProvider.InitRepository(repo);

                return(repo);
            }

            throw new InvalidProgramException(entityType.FullName + " 类型没有对应的仓库,创建仓库失败!");

            //实体类必须编写对应的 EntityRepository 类型,不再支持生成默认类型。
            ////如果上面在约定中没有找到,则直接生成一个默认的实体仓库。
            //return this.CreateDefaultRepository(entityType);
        }
Пример #16
0
        /// <summary>
        /// 通过列表类找到约定项
        /// </summary>
        /// <param name="listType"></param>
        /// <returns></returns>
        public static EntityMatrix FindByList(Type listType)
        {
            if (listType == null) throw new ArgumentNullException("listType");

            var item = FastFindByListType(listType);

            if (item == null)
            {
                var entityType = Convention_EntityForList(listType);
                var rpType = Convention_RepositoryForEntity(entityType);
                item = new EntityMatrix(entityType, listType, rpType);
                Add(item);
            }

            return item;
        }
Пример #17
0
        /// <summary>
        /// 通过仓库类找到约定项
        /// </summary>
        /// <param name="repositoryType"></param>
        /// <returns></returns>
        public static EntityMatrix FindByRepository(Type repositoryType)
        {
            if (repositoryType == null) return null;

            var item = FastFindByRepositoryType(repositoryType);

            if (item == null)
            {
                var entityType = Convention_EntityForRepository(repositoryType);
                var listType = Convention_ListForEntity(entityType);
                item = new EntityMatrix(entityType, listType, repositoryType);
                Add(item);
            }

            return item;
        }
Пример #18
0
 internal static void TryAddRepository(Type repositoryType)
 {
     var attri = repositoryType.GetSingleAttribute<RepositoryForAttribute>();
     if (attri != null)
     {
         Type entityType  = attri.EntityType;
         var listType = Convention_ListForEntity(entityType);
         var item = new EntityMatrix(entityType, listType, repositoryType);
         Add(item);
     }
 }
Пример #19
0
        /// <summary>
        /// LiteDataTable 类型的扩展方法,实现 LiteDataTable 类型到 EntityList 类型的转换。
        /// </summary>
        /// <typeparam name="TEntityList"></typeparam>
        /// <param name="liteDataTable"></param>
        /// <param name="columnMapToProperty">
        /// 此参数表示表格中的列名是否直接映射实体的属性名。
        /// 如果传入 false,表示表格中的列名映射的是实体对应的数据库表的列名,而非属性名。
        /// 默认为 true。
        /// </param>
        /// <returns></returns>
        public static TEntityList ToEntityList <TEntityList>(this LiteDataTable liteDataTable, bool columnMapToProperty = true) where TEntityList : EntityList
        {
            var entityMatrix = EntityMatrix.FindByList(typeof(TEntityList));
            var repo         = RepositoryFacade.Find(entityMatrix.EntityType);

            //属性和对应列的键值对集合,为后面填充实体用。
            var propertyToColumnMappings = new List <PropertyToColumnMapping>(10);

            //初始化 liteDataTable 中所有列名的集合,为后面初始化 propertyToColumnMappings 和判断属性用 。
            var columns = liteDataTable.Columns;
            var tableColumnsNameList = new List <string>();

            for (int i = 0, c = columns.Count; i < c; i++)
            {
                tableColumnsNameList.Add(columns[i].ColumnName);
            }

            //当表格中的列名映射的是实体对应的数据库表的列名,而非属性名的转换方法。
            if (!columnMapToProperty)
            {
                var entityPropertyMetaList = repo.EntityMeta.EntityProperties;
                for (int i = 0, c = entityPropertyMetaList.Count; i < c; i++)
                {
                    var propertyMeta   = entityPropertyMetaList[i];
                    var manageProperty = propertyMeta.ManagedProperty;
                    if (!manageProperty.IsReadOnly)
                    {
                        //这个位置是针对于时间戳的那几个字段 columnMeta 不为空 ,但是映射到数据库的 columnName 这个属性是空的。
                        //还有种情况是 columnMeta 为空,比如当对应的属性为 treeIndex。
                        var columnMeta = propertyMeta.ColumnMeta;
                        var columnName = columnMeta == null ? propertyMeta.Name : columnMeta.ColumnName ?? propertyMeta.Name;

                        for (int j = 0, c2 = tableColumnsNameList.Count; j < c2; j++)
                        {
                            if (tableColumnsNameList.Contains(columnName))
                            {
                                propertyToColumnMappings.Add(new PropertyToColumnMapping
                                {
                                    Property   = manageProperty,
                                    ColumnName = columnName
                                });
                            }
                        }
                    }
                }
            }
            else
            {
                var propertyList = repo.EntityMeta.ManagedProperties.GetCompiledProperties();
                for (int i = 0, c = propertyList.Count; i < c; i++)
                {
                    var property     = propertyList[i];
                    var propertyName = property.Name;
                    if (tableColumnsNameList.Contains(propertyName) && !property.IsReadOnly)
                    {
                        propertyToColumnMappings.Add(new PropertyToColumnMapping
                        {
                            Property   = property,
                            ColumnName = propertyName
                        });
                    }
                }
            }

            return(ConvertEntitiesIntoList(liteDataTable, repo, propertyToColumnMappings) as TEntityList);
        }
Пример #20
0
        private static void Add(EntityMatrix item)
        {
            try
            {
                _rwLock.EnterReadLock();

                if (!_entityIndex.ContainsKey(item.EntityType))
                {
                    _entityIndex.Add(item.EntityType, item);
                    if (item.ListType != null)
                    {
                        _listIndex.Add(item.ListType, item);
                    }
                    if (item.RepositoryType != null)
                    {
                        _repositoryIndex.Add(item.RepositoryType, item);
                    }
                }
            }
            finally
            {
                _rwLock.ExitReadLock();
            }
        }