Ejemplo n.º 1
0
        /// <summary>
        /// 注册插件定义
        /// </summary>
        /// <param name="config">系统配置</param>
        /// <param name="applicationPartManager">应用程序部件管理器</param>
        /// <param name="plug">插件信息</param>
        /// <returns>Assembly</returns>
        private static Assembly RegisterPluginDefinition(OarmsConfig config, ApplicationPartManager applicationPartManager, string plug)
        {
            //we can now register the plugin definition
            Assembly pluginAssembly;

            try
            {
                pluginAssembly = Assembly.LoadFrom(plug);
            }
            catch (FileLoadException)
            {
                if (config.UseUnsafeLoadAssembly)
                {
                    //如果应用程序已经从Web复制,则会将其标记为Web应用程序
                    //即便它是在本机计算机中,也可以通过更改文件的属性来更改插件的名称
                    //或者可以使用<loadFromRemoteSources>来标记授予程序集完全信任权限,作为替代的方法
                    //也可以使用unsafeloadFrom方法加载操作系统标记为的本地程序集
                    //从Web中加载已经加载了的文件
                    //http://go.microsoft.com/fwlink/?LinkId=155569 获取更多信息
                    pluginAssembly = Assembly.UnsafeLoadFrom(plug);
                }
                else
                {
                    throw;
                }
            }

            Debug.WriteLine("添加到应用程序部件: '{0}'", pluginAssembly.FullName);
            applicationPartManager.ApplicationParts.Add(new AssemblyPart(pluginAssembly));

            return(pluginAssembly);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// 通过Autofac注册程序集
        /// </summary>
        /// <param name="config"></param>
        /// <param name="services"></param>
        /// <param name="typeFinder"></param>
        /// <returns></returns>
        protected virtual IServiceProvider RegisterDependencies(OarmsConfig config, IServiceCollection services, ITypeFinder typeFinder)
        {
            var containerBuilder = new ContainerBuilder();

            //注册系统引擎
            containerBuilder.RegisterInstance(this).As <IEngine>().SingleInstance();
            //注册类型查找器
            containerBuilder.RegisterInstance(typeFinder).As <ITypeFinder>().SingleInstance();
            //通过程序集查找依赖注入的提供器
            var dependencyRegistrars = typeFinder.FindClassesOfType <IDependencyRegistrar>();
            //创建依赖注入的实例并对其进行排序
            var instances = dependencyRegistrars
                            .Select(dependencyRegistrar => (IDependencyRegistrar)Activator.CreateInstance(dependencyRegistrar))
                            .OrderBy(dependencyRegistrar => dependencyRegistrar.Order);

            //遍历所有注入的程序集
            foreach (var dependencyRegistrar in instances)
            {
                dependencyRegistrar.Register(containerBuilder, typeFinder, config);
            }
            //已注册的程序集通过Autofac容器将进行注入
            containerBuilder.Populate(services);
            //创建服务提供器
            _serviceProvider = new AutofacServiceProvider(containerBuilder.Build());
            return(_serviceProvider);
        }
Ejemplo n.º 3
0
 public RedisCacheManage(IRedisCache redisCache, IRedisConnectionWrapper redisConnectionWrapper, OarmsConfig config)
 {
     if (string.IsNullOrEmpty(config.RedisCachingConnectionString))
     {
         throw new Exception("Redis连接字符串不能为空!");
     }
     this._perRequestCacheManager = redisCache;
     this._connectionWrapper      = redisConnectionWrapper;
     this._db = _connectionWrapper.GetDatabase();
 }
Ejemplo n.º 4
0
        /// <summary>
        /// 初始化
        /// </summary>
        /// <param name="applicationPartManager">应用程序部件管理器</param>
        /// <param name="config">系统配置</param>
        public static void Initialize(ApplicationPartManager applicationPartManager, OarmsConfig config)
        {
            if (applicationPartManager == null)
            {
                throw new ArgumentNullException(nameof(applicationPartManager));
            }

            if (config == null)
            {
                throw new ArgumentNullException(nameof(config));
            }

            using (new WriteLockDisposable(Locker))
            {
                // 在该处添加详细的异常处理, 这是由于在应用程序启动时发生的,可能会阻止应用程序的启动
                var pluginFolder = _fileProvider.MapPath(OarmsPluginDefaults.Path);
                _shadowCopyFolder        = _fileProvider.MapPath(OarmsPluginDefaults.ShadowCopyPath);
                _reserveShadowCopyFolder = _fileProvider.Combine(_fileProvider.MapPath(OarmsPluginDefaults.ShadowCopyPath), $"{OarmsPluginDefaults.ReserveShadowCopyPathName}{DateTime.Now.ToFileTimeUtc()}");

                var referencedPlugins   = new List <PluginDescriptor>();
                var incompatiblePlugins = new List <string>();

                try
                {
                    var installedPluginSystemNames = GetInstalledPluginNames(_fileProvider.MapPath(OarmsPluginDefaults.InstalledPluginsFilePath));

                    Debug.WriteLine("正在创建影像的文件夹并查询dll");
                    //确保文件夹已创建
                    _fileProvider.CreateDirectory(pluginFolder);
                    _fileProvider.CreateDirectory(_shadowCopyFolder);

                    //获取bin下面的所有文件
                    var binFiles = _fileProvider.GetFiles(_shadowCopyFolder, "*", false);
                    if (config.ClearPluginShadowDirectoryOnStartup)
                    {
                        //清除复制的副本文件
                        foreach (var f in binFiles)
                        {
                            if (_fileProvider.GetFileName(f).Equals("placeholder.txt", StringComparison.InvariantCultureIgnoreCase))
                            {
                                continue;
                            }

                            Debug.WriteLine("删除中 " + f);
                            try
                            {
                                //忽然index.htm
                                var fileName = _fileProvider.GetFileName(f);
                                if (fileName.Equals("index.htm", StringComparison.InvariantCultureIgnoreCase))
                                {
                                    continue;
                                }

                                _fileProvider.DeleteFile(f);
                            }
                            catch (Exception exc)
                            {
                                Debug.WriteLine("删除文件时出错 " + f + ". Exception: " + exc);
                            }
                        }

                        //删除所有保留的文件夹
                        foreach (var directory in _fileProvider.GetDirectories(_shadowCopyFolder, OarmsPluginDefaults.ReserveShadowCopyPathNamePattern))
                        {
                            try
                            {
                                _fileProvider.DeleteDirectory(directory);
                            }
                            catch
                            {
                                //do nothing
                            }
                        }
                    }

                    //加载描述文件
                    foreach (var dfd in GetDescriptionFilesAndDescriptors(pluginFolder))
                    {
                        var descriptionFile  = dfd.Key;
                        var pluginDescriptor = dfd.Value;

                        //确保插件的版本是有效的
                        if (!pluginDescriptor.SupportedVersions.Contains(OarmsVersion.CurrentVersion, StringComparer.InvariantCultureIgnoreCase))
                        {
                            incompatiblePlugins.Add(pluginDescriptor.SystemName);
                            continue;
                        }

                        //验证插件命名
                        if (string.IsNullOrWhiteSpace(pluginDescriptor.SystemName))
                        {
                            throw new Exception($"'{descriptionFile}' 没有系统命名. 重新为插件进行唯一命名并重新编译.");
                        }
                        if (referencedPlugins.Contains(pluginDescriptor))
                        {
                            throw new Exception($"'{pluginDescriptor.SystemName}' 插件命名在系统中已存在");
                        }

                        //设置已安装属性
                        pluginDescriptor.Installed = installedPluginSystemNames
                                                     .FirstOrDefault(x => x.Equals(pluginDescriptor.SystemName, StringComparison.InvariantCultureIgnoreCase)) != null;

                        try
                        {
                            var directoryName = _fileProvider.GetDirectoryName(descriptionFile);
                            if (string.IsNullOrEmpty(directoryName))
                            {
                                throw new Exception($"无法为插件'{_fileProvider.GetFileName(descriptionFile)}'描述文件解析目录");
                            }

                            //获取插件中所有DLL的列表(不在bin中)
                            var pluginFiles = _fileProvider.GetFiles(directoryName, "*.dll", false)
                                              //确保没有注册复制的副本插件
                                              .Where(x => !binFiles.Select(q => q).Contains(x))
                                              .Where(x => IsPackagePluginFolder(_fileProvider.GetDirectoryName(x)))
                                              .ToList();

                            //其他插件描述信息
                            var mainPluginFile = pluginFiles
                                                 .FirstOrDefault(x => _fileProvider.GetFileName(x).Equals(pluginDescriptor.AssemblyFileName, StringComparison.InvariantCultureIgnoreCase));

                            //插件目录错误
                            if (mainPluginFile == null)
                            {
                                incompatiblePlugins.Add(pluginDescriptor.SystemName);
                                continue;
                            }

                            pluginDescriptor.OriginalAssemblyFile = mainPluginFile;

                            //复制主插件副本
                            pluginDescriptor.ReferencedAssembly = PerformFileDeploy(mainPluginFile, applicationPartManager, config);

                            //加载所有其他引用的程序集
                            foreach (var plugin in pluginFiles
                                     .Where(x => !_fileProvider.GetFileName(x).Equals(_fileProvider.GetFileName(mainPluginFile), StringComparison.InvariantCultureIgnoreCase))
                                     .Where(x => !IsAlreadyLoaded(x)))
                            {
                                PerformFileDeploy(plugin, applicationPartManager, config);
                            }

                            //初始化插件类型(每个插件只能是一个程序集)
                            foreach (var t in pluginDescriptor.ReferencedAssembly.GetTypes())
                            {
                                if (typeof(IPlugin).IsAssignableFrom(t))
                                {
                                    if (!t.IsInterface)
                                    {
                                        if (t.IsClass && !t.IsAbstract)
                                        {
                                            pluginDescriptor.PluginType = t;
                                            break;
                                        }
                                    }
                                }
                            }

                            referencedPlugins.Add(pluginDescriptor);
                        }
                        catch (ReflectionTypeLoadException ex)
                        {
                            //添加插件名称,便于快速识别有问题的插件
                            var msg = $"Plugin '{pluginDescriptor.FriendlyName}'. ";
                            foreach (var e in ex.LoaderExceptions)
                            {
                                msg += e.Message + Environment.NewLine;
                            }

                            var fail = new Exception(msg, ex);
                            throw fail;
                        }
                        catch (Exception ex)
                        {
                            //添加插件名称,便于快速识别有问题的插件
                            var msg = $"Plugin '{pluginDescriptor.FriendlyName}'. {ex.Message}";

                            var fail = new Exception(msg, ex);
                            throw fail;
                        }
                    }
                }
                catch (Exception ex)
                {
                    var msg = string.Empty;
                    for (var e = ex; e != null; e = e.InnerException)
                    {
                        msg += e.Message + Environment.NewLine;
                    }

                    var fail = new Exception(msg, ex);
                    throw fail;
                }

                ReferencedPlugins   = referencedPlugins;
                IncompatiblePlugins = incompatiblePlugins;
            }
        }
Ejemplo n.º 5
0
        /// <summary>
        /// 执行部署文件
        /// </summary>
        /// <param name="plug">插件信息</param>
        /// <param name="applicationPartManager">应用程序部件管理器</param>
        /// <param name="config">系统配置</param>
        /// <param name="shadowCopyPath">复制路径</param>
        /// <returns>Assembly</returns>
        private static Assembly PerformFileDeploy(string plug, ApplicationPartManager applicationPartManager, OarmsConfig config, string shadowCopyPath = "")
        {
            var parent = string.IsNullOrEmpty(plug) ? string.Empty : _fileProvider.GetParentDirectory(plug);

            if (string.IsNullOrEmpty(parent))
            {
                throw new InvalidOperationException($"{_fileProvider.GetFileName(plug)}插件存在的目录是在系统允许的OarmsCommerce文件夹层次结构之外");
            }

            if (!config.UsePluginsShadowCopy)
            {
                return(RegisterPluginDefinition(config, applicationPartManager, plug));
            }

            //为了避免可能出现的异常,将库文件复制到 ~/Plugins/bin/ 目录中
            if (string.IsNullOrEmpty(shadowCopyPath))
            {
                shadowCopyPath = _shadowCopyFolder;
            }

            _fileProvider.CreateDirectory(shadowCopyPath);
            var shadowCopiedPlug = ShadowCopyFile(plug, shadowCopyPath);

            Assembly shadowCopiedAssembly = null;

            try
            {
                shadowCopiedAssembly = RegisterPluginDefinition(config, applicationPartManager, shadowCopiedPlug);
            }
            catch (FileLoadException)
            {
                if (!config.CopyLockedPluginAssembilesToSubdirectoriesOnStartup || !shadowCopyPath.Equals(_shadowCopyFolder))
                {
                    throw;
                }
            }

            return(shadowCopiedAssembly ?? PerformFileDeploy(plug, applicationPartManager, config, _reserveShadowCopyFolder));
        }