/// <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); }
/// <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); }
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(); }
/// <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; } }
/// <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)); }