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); } } } })); }
static void ConfigurePlugin <TPlugin>() where TPlugin : GraffitiEvent, ISupportsMemento { TPlugin plugin = PluginHelper.GetPluginWithCurrentSettings <TPlugin>(); IMemento state = plugin.CreateMemento(); PluginMigrator.MigrateSettings(true, false, state, state); }
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); }
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); }
public TPlugin Load <TPlugin>() where TPlugin : class, IHostViewAddIn { TPlugin plugin = this.GetPlugin <TPlugin>(); if (plugin != null) { return(plugin); } plugin = this.LoadPlugin <TPlugin>(); return(plugin); }
// 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); } }
/// <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); } } }
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); }
/// <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); }
// 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>); }
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); }
public PluginContainer(AppDomain domain, TPlugin plugin, TModel model) { Domain = domain; Plugin = plugin; Model = model; }
public PluginContainer(AppDomain domain, TPlugin plugin) { Domain = domain; Plugin = plugin; }
public PluginInstance(TPlugin instance, T plugin, bool @default) { Instance = instance; Plugin = plugin; IsDefault = @default; }