Exemplo n.º 1
0
        /// <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;
            }
        }