Пример #1
0
    public TPlugin(string path, bool Initialize = false)
    {
        FilePath = path;
        InitializeImmediately = Initialize;

        AppSetup = new AppDomainSetup();
        AppSetup.ApplicationBase = AppDomain.CurrentDomain.BaseDirectory;
        AppDomain = AppDomain.CreateDomain(FilePath, null, AppSetup);
        AppDomain.SetData("Plugin", this);
        AppDomain.DoCallBack(new CrossAppDomainDelegate(() =>
        {
            //We are now inside the new AppDomain, every other variable is now invalid since this AppDomain cannot see into the main one
            TPlugin plugin = AppDomain.CurrentDomain.GetData("Plugin") as TPlugin;
            if (plugin != null)
            {
                plugin.Assembly = Assembly.LoadFrom(plugin.FilePath);
                if (InitializeImmediately)    //You cannot use the "Initialize" parameter here, it goes out of scope for this AppDomain
                {
                    plugin.ClassType = plugin.Assembly.GetExportedTypes()[0];
                    if (plugin.ClassType != null && plugin.ClassType.IsClass)
                    {
                        plugin.ClassInstance = Activator.CreateInstance(plugin.ClassType);
                        MethodInfo info      = plugin.ClassType.GetMethod("Initializer");
                        info.Invoke(plugin.ClassInstance, null);
                    }
                }
            }
        }));
    }
Пример #2
0
        static void ConfigurePlugin <TPlugin>()
            where TPlugin : GraffitiEvent, ISupportsMemento
        {
            TPlugin  plugin = PluginHelper.GetPluginWithCurrentSettings <TPlugin>();
            IMemento state  = plugin.CreateMemento();

            PluginMigrator.MigrateSettings(true, false, state, state);
        }
Пример #3
0
        public void Unload <TPlugin>() where TPlugin : class, IHostViewAddIn
        {
            TPlugin plugin = this.GetPlugin <TPlugin>();

            if (plugin == null)
            {
                throw new InvalidOperationException("The plugin has already been unloaded.");
            }

            this.UnloadInternal(plugin);
        }
Пример #4
0
    public void CallBack()
    {
        TPlugin plugin = AppDomain.CurrentDomain.GetData("Plugin") as TPlugin;

        if (plugin != null)
        {
            MethodInfo info = plugin.ClassType.GetMethod(AppDomain.CurrentDomain.GetData("FunctionName") as string);
            info.Invoke(plugin.ClassInstance, AppDomain.CurrentDomain.GetData("FunctionArgs") as object[]);
        }

        //This is how to return back since DoCallBack does not support returns.
        AppDomain.CurrentDomain.SetData("FunctionReturn", null);
    }
Пример #5
0
        public TPlugin Load <TPlugin>() where TPlugin : class, IHostViewAddIn
        {
            TPlugin plugin = this.GetPlugin <TPlugin>();

            if (plugin != null)
            {
                return(plugin);
            }

            plugin = this.LoadPlugin <TPlugin>();

            return(plugin);
        }
Пример #6
0
        // ReSharper disable once UnusedParameter.Local
        public static void Connect <TPlugin>() where TPlugin : HSPIBase, new()
        {
            Console.WriteLine("Test Plugin");

            // create an instance of our plugin.
            var myPlugin = new TPlugin();

            // Get our plugin to connect to Homeseer
            Console.WriteLine("\nConnecting to Homeseer at " + ServerAddress + ":" + ServerPort + " ...");
            try
            {
                myPlugin.Connect(ServerAddress, ServerPort);

                // got this far then success
                Console.WriteLine("  connection to homeseer successful.\n");
            }
            catch (Exception ex)
            {
                Console.WriteLine("  connection to homeseer failed: " + ex.Message);
                return;
            }

            // let the plugin do it's thing, wait until it shuts down or the connection to homeseer fails.
            try
            {
                while (true)
                {
                    // do nothing for a bit
                    Thread.Sleep(200);

                    // test the connection to homeseer
                    if (!myPlugin.Connected)
                    {
                        Console.WriteLine("Connection to homeseer lost, exiting");
                        break;
                    }

                    // test for a shutdown signal
                    if (myPlugin.Shutdown)
                    {
                        Console.WriteLine("Plugin has been shut down, exiting");
                        break;
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("Unhandled exception from Plugin: " + ex.Message);
            }
        }
Пример #7
0
        /// <summary>
        /// 实现了指定接口或类型 的启用插件
        /// </summary>
        /// <typeparam name="TPlugin">可以是一个接口,一个抽象类,一个普通实现类, 只要实现了 <see cref="IPlugin"/>即可</typeparam>
        /// <returns></returns>
        public IEnumerable <TPlugin> EnablePlugins <TPlugin>()
            where TPlugin : IPlugin // BasePlugin
        {
            // TODO: 目前这里还有问题, 不应该写为 BasePlugin, 不利于扩展, 不利于插件开发者自己实现 Install , Uninstall等

            // 1.所有启用的插件 PluginId
            var            pluginConfigModel = PluginConfigModelFactory.Create();
            IList <string> enablePluginIds   = pluginConfigModel.EnabledPlugins;

            foreach (var pluginId in enablePluginIds)
            {
                if (PluginsLoadContexts.Any(pluginId))
                {
                    // 2.找到插件对应的Context
                    var context = PluginsLoadContexts.Get(pluginId);
                    // 3.找插件 主 Assembly
                    // Assembly.FullName: HelloWorld, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
                    Assembly pluginMainAssembly = context.Assemblies.Where(m => m.FullName.StartsWith($"{pluginId}, Version=")).FirstOrDefault();
                    if (pluginMainAssembly == null)
                    {
                        continue;
                    }
                    // 4.从插件主Assembly中 找实现了 TPlugin 接口的 Type, 若有多个,只要一个
                    Type pluginType = pluginMainAssembly.ExportedTypes.Where(m =>
                                                                             (m.BaseType == typeof(TPlugin) || m.GetInterfaces().Contains(typeof(TPlugin)))
                                                                             &&
                                                                             !m.IsInterface
                                                                             &&
                                                                             !m.IsAbstract
                                                                             ).FirstOrDefault();
                    if (pluginType == null)
                    {
                        continue;
                    }
                    // 5.实例化插件 Type
                    //(TPlugin)Activator.CreateInstance(pluginType,);
                    //try to resolve plugin as unregistered service
                    //object instance = EngineContext.Current.ResolveUnregistered(pluginType);
                    object instance = ResolveUnregistered(pluginType);
                    //try to get typed instance
                    TPlugin typedInstance = (TPlugin)instance;
                    if (typedInstance == null)
                    {
                        continue;
                    }

                    yield return(typedInstance);
                }
            }
        }
Пример #8
0
        void CreateCategory <TPlugin>() where TPlugin : GraffitiEvent, IPluginConfigurationProvider
        {
            TPlugin plugin = PluginHelper.GetPluginWithCurrentSettings <TPlugin>();

            if (_categoryRepository.GetCategory(plugin.CategoryName) != null)
            {
                throw new InvalidOperationException(String.Format("The category '{0}' already exists.", plugin.CategoryName));
            }

            Category category = new Category {
                Name = plugin.CategoryName, ParentId = -1
            };

            _categoryRepository.AddCategory(category);
        }
Пример #9
0
        /// <summary>
        /// Get the instance of the plugin
        /// </summary>
        /// <typeparam name="TPlugin">Type of the plugin</typeparam>
        /// <returns>Plugin instance</returns>
        public virtual TPlugin Instance <TPlugin>() where TPlugin : class, IPlugin
        {
            //try to resolve plugin as unregistered service
            object instance = EngineContext.Current.ResolveUnregistered(PluginType);

            //try to get typed instance
            TPlugin typedInstance = instance as TPlugin;

            if (typedInstance != null)
            {
                typedInstance.PluginDescriptor = this;
            }

            return(typedInstance);
        }
Пример #10
0
        // Public so it can be used by custom plugins Get method
        public static ABSTweenPlugin <T1, T2, TPlugOptions> GetCustomPlugin <TPlugin, T1, T2, TPlugOptions>()
            where TPlugin : ITweenPlugin, new()
            where TPlugOptions : struct
        {
            Type         t = typeof(TPlugin);
            ITweenPlugin plugin;

            if (_customPlugins == null)
            {
                _customPlugins = new Dictionary <Type, ITweenPlugin>(_MaxCustomPlugins);
            }
            else if (_customPlugins.TryGetValue(t, out plugin))
            {
                return(plugin as ABSTweenPlugin <T1, T2, TPlugOptions>);
            }

            plugin = new TPlugin();
            _customPlugins.Add(t, plugin);
            return(plugin as ABSTweenPlugin <T1, T2, TPlugOptions>);
        }
Пример #11
0
        void CreateNavigationLink <TPlugin>() where TPlugin : GraffitiEvent, IPluginConfigurationProvider, new()
        {
            TPlugin  plugin   = PluginHelper.GetPluginWithCurrentSettings <TPlugin>();
            Category category = _categoryRepository.GetCategory(plugin.CategoryName);

            // Dynamic navigation items for categories are automatically created if the dynamic navigation items are empty.
            NavigationSettings settings = NavigationSettings.Get();

            if (settings.SafeItems().Exists(dni => dni.NavigationType == DynamicNavigationType.Category && dni.CategoryId == category.Id))
            {
                // The dynamic navigation item already exists.
                return;
            }

            DynamicNavigationItem item = new DynamicNavigationItem
            {
                NavigationType = DynamicNavigationType.Category,
                CategoryId     = category.Id,
                Id             = Guid.NewGuid()
            };

            NavigationSettings.Add(item);
        }
Пример #12
0
 public PluginContainer(AppDomain domain, TPlugin plugin, TModel model)
 {
     Domain = domain;
     Plugin = plugin;
     Model  = model;
 }
Пример #13
0
 public PluginContainer(AppDomain domain, TPlugin plugin)
 {
     Domain = domain;
     Plugin = plugin;
 }
Пример #14
0
 public PluginInstance(TPlugin instance, T plugin, bool @default)
 {
     Instance  = instance;
     Plugin    = plugin;
     IsDefault = @default;
 }