Ejemplo n.º 1
0
        /// <summary>
        /// 启动 XNCF 模块引擎,包括初始化扫描和注册等过程
        /// </summary>
        /// <returns></returns>
        public static string StartEngine(this IServiceCollection services, IConfiguration configuration)
        {
            StringBuilder sb = new StringBuilder();

            sb.AppendLine($"[{SystemTime.Now}] 开始初始化扫描 XncfModules");
            var scanTypesCount = 0;
            var hideTypeCount  = 0;
            ConcurrentDictionary <Type, ScanTypeKind> types = new ConcurrentDictionary <Type, ScanTypeKind>();

            //所有 XNCF 模块,包括被忽略的。
            //var cache = CacheStrategyFactory.GetObjectCacheStrategyInstance();
            //using (cache.BeginCacheLock("Senparc.Ncf.XncfBase.Register", "Scan")) //在注册阶段还未完成缓存配置
            {
                try
                {
                    //遍历所有程序集
                    foreach (var a in AppDomain.CurrentDomain.GetAssemblies())
                    {
                        scanTypesCount++;
                        var aTypes = a.GetTypes();
                        foreach (var t in aTypes)
                        {
                            if (t.IsAbstract)
                            {
                                continue;
                            }

                            if (t.GetInterfaces().Contains(typeof(IXncfRegister)))
                            {
                                types[t] = ScanTypeKind.IXncfRegister;
                            }
                            else if (t.GetInterfaces().Contains(typeof(IXncfFunction)))
                            {
                                types[t] = ScanTypeKind.IXncfFunction; /* 暂时不收录处理 */
                            }
                            else if (t.GetCustomAttributes(true).FirstOrDefault(z => z is XncfAutoConfigurationMappingAttribute) != null
                                     /*&& t.GetInterfaces().Contains(typeof(IEntityTypeConfiguration<>))*/)
                            {
                                types[t] = ScanTypeKind.XncfAutoConfigurationMappingAttribute;
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine($"扫描程集异常退出,可能无法获得完整程序集信息:{ex.Message}");
                }

                sb.AppendLine($"[{SystemTime.Now}] 满足条件对象:{types.Count()}");

                //先注册 XncfRegister
                {
                    //筛选
                    var allTypes = types.Where(z => z.Value == ScanTypeKind.IXncfRegister /* && z.Key.GetInterfaces().Contains(typeof(IXncfRegister))*/)
                                   .Select(z => z.Key);
                    //按照优先级进行排序
                    var orderedTypes = allTypes.OrderByDescending(z =>
                    {
                        var orderAttribute = z.GetCustomAttributes(true).FirstOrDefault(attr => attr is XncfOrderAttribute) as XncfOrderAttribute;
                        if (orderAttribute != null)
                        {
                            return(orderAttribute.Order);
                        }
                        return(0);
                    });


                    foreach (var type in orderedTypes)
                    {
                        sb.AppendLine($"[{SystemTime.Now}] 扫描到 IXncfRegister:{type.FullName}");

                        var register = type.Assembly.CreateInstance(type.FullName) as IXncfRegister;

                        if (!RegisterList.Contains(register))
                        {
                            if (RegisterList.Exists(z => z.Uid.Equals(register.Uid, StringComparison.OrdinalIgnoreCase)))
                            {
                                throw new XncfFunctionException("已经存在相同 Uid 的模块:" + register.Uid);
                            }

                            if (register.IgnoreInstall)
                            {
                                hideTypeCount++;
                            }
                            RegisterList.Add(register); //只有允许安装的才进行注册,否则执行完即结束
                            services.AddScoped(type);   //DI 中注册
                            foreach (var functionType in register.Functions)
                            {
                                services.AddScoped(functionType);//DI 中注册
                            }
                        }
                    }

                    #region 暂时不收录 IXncfFunction

                    /* 暂时不收录 */
                    ////再扫描具体方法
                    //foreach (var type in types.Where(z => z != null && z.GetInterfaces().Contains(typeof(IXncfFunction))))
                    //{
                    //    sb.AppendLine($"[{SystemTime.Now}] 扫描到 IXncfFunction:{type.FullName}");

                    //    if (!ModuleFunctionCollection.ContainsKey(type))
                    //    {
                    //        throw new NCFExceptionBase($"{type.FullName} 未能提供正确的注册方法!");
                    //    }

                    //    var function = type as IXncfFunction;
                    //    ModuleFunctionCollection[type].Add(function);
                    //}

                    #endregion
                }

                //处理 XncfAutoConfigurationMappingAttribute
                {
                    var allTypes = types.Where(z => z.Value == ScanTypeKind.XncfAutoConfigurationMappingAttribute).Select(z => z.Key);
                    foreach (var type in allTypes)
                    {
                        var obj = type.Assembly.CreateInstance(type.FullName);
                        XncfAutoConfigurationMappingList.Add(obj /*as IEntityTypeConfiguration<EntityBase>*/);
                    }
                }
            }

            var scanResult = "初始化扫描结束,共扫描 {scanTypesCount} 个程序集";
            if (hideTypeCount > 0)
            {
                scanResult += $"。其中 {hideTypeCount} 个程序集为非安装程序集,不会被缓存";
            }
            sb.AppendLine($"[{SystemTime.Now}] {scanResult}");


            //Repository & Service
            services.AddScoped(typeof(Senparc.Ncf.Repository.IRepositoryBase <>), typeof(Senparc.Ncf.Repository.RepositoryBase <>));
            services.AddScoped(typeof(ServiceBase <>));
            services.AddScoped(typeof(IServiceBase <>), typeof(ServiceBase <>));

            //ConfigurationMapping
            services.AddScoped(typeof(ConfigurationMappingBase <>));
            services.AddScoped(typeof(ConfigurationMappingWithIdBase <,>));

            //微模块进行 Service 注册
            foreach (var xncfRegister in RegisterList)
            {
                xncfRegister.AddXncfModule(services, configuration);
            }
            sb.AppendLine($"[{SystemTime.Now}] 完成模块 services.AddXncfModule():共扫描 {scanTypesCount} 个程序集");

            //支持 AutoMapper
            //引入当前系统
            services.AddAutoMapper(z => z.AddProfile <Core.AutoMapper.SystemProfile>());
            //引入所有模块
            services.AddAutoMapper(z => z.AddProfile <AutoMapper.XncfModuleProfile>());

            return(sb.ToString());
        }
Ejemplo n.º 2
0
 /// <summary>
 /// 判断指定名称的模块是否已注册(推荐)
 /// </summary>
 /// <param name="xncfRegister">XncfRegister</param>
 /// <returns></returns>
 public static bool IsRegistered(IXncfRegister xncfRegister) => RegisterList.Exists(z => z.Uid == xncfRegister.Uid);
Ejemplo n.º 3
0
        /// <summary>
        /// 启动 XSCF 模块引擎,包括初始化扫描和注册等过程,通常在 Startup.cs 中的 ConfigureServices() 方法中执行
        /// </summary>
        /// <returns></returns>
        public static string StartEngine(this IServiceCollection services, IConfiguration configuration)
        {
            StringBuilder sb = new StringBuilder();

            sb.AppendLine($"[{SystemTime.Now}] 开始初始化扫描 XscfModules");
            var scanTypesCount       = 0;
            var hideTypeCount        = 0;
            IEnumerable <Type> types = null;

            //所有 XSCF 模块,包括被忽略的。
            //var cache = CacheStrategyFactory.GetObjectCacheStrategyInstance();
            //using (cache.BeginCacheLock("Senparc.Scf.XscfBase.Register", "Scan")) //在注册阶段还未完成缓存配置
            {
                try
                {
                    types = AppDomain.CurrentDomain.GetAssemblies()
                            .SelectMany(a =>
                    {
                        try
                        {
                            scanTypesCount++;
                            var aTypes = a.GetTypes();
                            return(aTypes.Where(t =>
                                                !t.IsAbstract &&
                                                (t.GetInterfaces().Contains(typeof(IXscfRegister)) ||
                                                 t.GetInterfaces().Contains(typeof(IXscfFunction) /* 暂时不收录 */)
                                                )));
                        }
                        catch (Exception ex)
                        {
                            sb.AppendLine($"[{SystemTime.Now}] 自动扫描程序集异常:" + a.FullName);
                            SenparcTrace.SendCustomLog("XscfRegister() 自动扫描程序集异常:" + a.FullName, ex.ToString());
                            return(new List <Type>());         //不能 return null
                        }
                    });
                }
                catch (Exception ex)
                {
                    Console.WriteLine($"扫描程集异常退出,可能无法获得完整程序集信息:{ex.Message}");
                }

                if (types != null)
                {
                    sb.AppendLine($"[{SystemTime.Now}] 满足条件对象:{types.Count()}");

                    //先注册 XscfRegister

                    //筛选
                    var allTypes = types.Where(z => z != null && z.GetInterfaces().Contains(typeof(IXscfRegister)));
                    //按照优先级进行排序
                    var orderedTypes = allTypes.OrderByDescending(z =>
                    {
                        var orderAttribute = z.GetCustomAttributes(true).FirstOrDefault(z => z is XscfOrderAttribute) as XscfOrderAttribute;
                        if (orderAttribute != null)
                        {
                            return(orderAttribute.Order);
                        }
                        return(0);
                    });

                    foreach (var type in orderedTypes)
                    {
                        sb.AppendLine($"[{SystemTime.Now}] 扫描到 IXscfRegister:{type.FullName}");

                        var register = type.Assembly.CreateInstance(type.FullName) as IXscfRegister;

                        if (!RegisterList.Contains(register))
                        {
                            if (RegisterList.Exists(z => z.Uid.Equals(register.Uid, StringComparison.OrdinalIgnoreCase)))
                            {
                                throw new XscfFunctionException("已经存在相同 Uid 的模块:" + register.Uid);
                            }

                            if (register.IgnoreInstall)
                            {
                                hideTypeCount++;
                            }
                            RegisterList.Add(register); //只有允许安装的才进行注册,否则执行完即结束
                            services.AddScoped(type);   //DI 中注册
                            foreach (var functionType in register.Functions)
                            {
                                services.AddScoped(functionType);//DI 中注册
                            }
                        }
                    }

                    /* 暂时不收录 */
                    ////再扫描具体方法
                    //foreach (var type in types.Where(z => z != null && z.GetInterfaces().Contains(typeof(IXscfFunction))))
                    //{
                    //    sb.AppendLine($"[{SystemTime.Now}] 扫描到 IXscfFunction:{type.FullName}");

                    //    if (!ModuleFunctionCollection.ContainsKey(type))
                    //    {
                    //        throw new SCFExceptionBase($"{type.FullName} 未能提供正确的注册方法!");
                    //    }

                    //    var function = type as IXscfFunction;
                    //    ModuleFunctionCollection[type].Add(function);
                    //}
                }
            }

            var scanResult = "初始化扫描结束,共扫描 {scanTypesCount} 个程序集";

            if (hideTypeCount > 0)
            {
                scanResult += $"。其中 {hideTypeCount} 个程序集为非安装程序集,不会被缓存";
            }
            sb.AppendLine($"[{SystemTime.Now}] {scanResult}");


            //微模块进行 Service 注册
            foreach (var xscfRegister in RegisterList)
            {
                xscfRegister.AddXscfModule(services, configuration);
            }
            sb.AppendLine($"[{SystemTime.Now}] 完成模块 services.AddXscfModule():共扫描 {scanTypesCount} 个程序集");

            //支持 AutoMapper
            //引入当前系统
            services.AddAutoMapper(z => z.AddProfile <Core.AutoMapper.SystemProfile>());
            //引入所有模块
            services.AddAutoMapper(z => z.AddProfile <AutoMapper.XscfModuleProfile>());

            return(sb.ToString());
        }
Ejemplo n.º 4
0
 /// <summary>
 /// 判断指定名称的模块是否已注册
 /// </summary>
 /// <param name="name"></param>
 /// <returns></returns>
 public static bool IsRegistered(string name) => RegisterList.Exists(z => z.Name == name);