/// <summary> /// 初始化 /// </summary> public static void Initialize() { using (new WriteLockDisposable(Locker)) { var pluginFolder = new DirectoryInfo(CommonHelper.MapPath(PluginsPath)); _shadowCopyFolder = new DirectoryInfo(CommonHelper.MapPath(ShadowCopyPath)); var referencedPlugins = new List <PluginDescriptor>(); var incompatiblePlugins = new List <string>(); _clearShadowDirectoryOnStartup = !String.IsNullOrEmpty(ConfigurationManager.AppSettings["ClearPluginsShadowDirectoryOnStartup"]) && Convert.ToBoolean(ConfigurationManager.AppSettings["ClearPluginsShadowDirectoryOnStartup"]); try { var installedPluginSystemNames = PluginFileParser.ParseInstalledPluginsFile(GetInstalledPluginsFilePath()); Debug.WriteLine("Creating shadow copy folder and querying for dlls"); Directory.CreateDirectory(pluginFolder.FullName); Directory.CreateDirectory(_shadowCopyFolder.FullName); //获取bin中所有文件的列表 var binFiles = _shadowCopyFolder.GetFiles("*", SearchOption.AllDirectories); if (_clearShadowDirectoryOnStartup) { foreach (var f in binFiles) { Debug.WriteLine("Deleting" + f.Name); try { File.Delete(f.FullName); } catch (Exception exc) { Debug.WriteLine("Error deleting file " + f.Name + ". Exception: " + exc); } } } ///加载描述文件 foreach (var dfd in GetDescriptionFilesAndDescriptors(pluginFolder)) { var descriptionFile = dfd.Key; var pluginDescriptor = dfd.Value; //var isSupport = pluginDescriptor.SupportedVersions.Contains(SunFrameworkVersion.CurrentVersion, StringComparer.InvariantCultureIgnoreCase); ///确保版本正确 if (!pluginDescriptor.SupportedVersions.Contains(SunFrameworkVersion.CurrentVersion, StringComparer.InvariantCultureIgnoreCase)) { incompatiblePlugins.Add(pluginDescriptor.SystemName); continue; } //some validation if (String.IsNullOrWhiteSpace(pluginDescriptor.SystemName)) { throw new Exception(string.Format("A plugin '{0}' has no system name. Try assigning the plugin a unique name and recompiling.", descriptionFile.FullName)); } if (referencedPlugins.Contains(pluginDescriptor)) { throw new Exception(string.Format("A plugin with '{0}' system name is already defined", pluginDescriptor.SystemName)); } //set 'Installed' property pluginDescriptor.Installed = installedPluginSystemNames .FirstOrDefault(x => x.Equals(pluginDescriptor.SystemName, StringComparison.InvariantCultureIgnoreCase)) != null; try { if (descriptionFile.Directory == null) { throw new Exception(string.Format("Directory cannot be resolved for '{0}' description file", descriptionFile.Name)); } //获取插件中所有dll的列表 (not in bin!) var pluginFiles = descriptionFile.Directory.GetFiles("*dll", SearchOption.AllDirectories) .Where(x => !binFiles.Select(q => q.Name).Contains(x.FullName)) .Where(x => IsPackagePluginFolder(x.Directory)) .ToList(); //插件其他描述信息 var mainPluginFile = pluginFiles .FirstOrDefault(x => x.Name.Equals(pluginDescriptor.PluginFileName, StringComparison.InvariantCultureIgnoreCase)); pluginDescriptor.OriginalAssemblyFile = mainPluginFile; //shadow copy main plugin file pluginDescriptor.ReferencedAssembly = PerformFileDeploy(mainPluginFile); //加载所有其他引用的程序集 foreach (var plugin in pluginFiles .Where(x => !x.Name.Equals(mainPluginFile.Name, StringComparison.InvariantCultureIgnoreCase)) .Where(x => !IsAlreadyLoaded(x))) { PerformFileDeploy(plugin); } //初始化插件(每个程序集只允许一个插件) 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) { //add a plugin name. this way we can easily identify a problematic plugin var msg = string.Format("Plugin '{0}'. ", pluginDescriptor.FriendlyName); foreach (var e in ex.LoaderExceptions) { msg += e.Message + Environment.NewLine; } var fail = new Exception(msg, ex); throw fail; } catch (Exception ex) { //add a plugin name. this way we can easily identify a problematic plugin var msg = string.Format("Plugin '{0}'. {1}", 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; } }