我正在实现一个基于插件的服务器架构,并且希望插件能够了解服务器状态,并且有一种将状态和结果报告回服务器的常用方法。
我的目的是定义一个在调用它们时传递给每个插件的上下文,插件会将状态信息报告回上下文。 然后,上下文将用于跟踪每个插件执行的每个任务的状态。
是否有在C#中创建自定义上下文的标准,或者是否有可以使用的通用DataGrid
对象?
所有上下文需要做的是存储属性,但我不确定哪个Context类最适合扩展或按原样使用。
在这种情况下,上下文将包含
1)每个插件读取的一组共享属性,用于管理它们的执行(db地址,用于查找要处理的项目的文件夹名称等)
2)一个字典,其中包含插件“Context
方法
3)关于流程成功/失败的状态信息
4)过程当前状态的记录(来自枚举的值)
我打算为此使用一个基本对象,但由于C#的各种库中有许多Execute
类,我在争论扩展现有的Context
对象是否会比从头开始写一个更好的选择。
观看有关MSDN的文献,这两种方法似乎都没有太多先例,我将非常感谢那些已经完成此任务的人的反馈。
答案 0 :(得分:2)
不要使用全局/静态上下文。这使得维护和测试应用程序变得更加困难。
相反,您可以在插件初始化期间定义上下文并将其作为实例传递给插件。类似的东西:
public interface IPlugin
{
void Init(ApplicationContext context)
// [.. other methods that plugins must implement ..]
}
就像您拥有相同的功能,但无需考虑[ThreadStatic]
和异步上下文。
我打算为此使用一个基本对象,但由于C#的各种库中有许多Context类,我在争论是否扩展现有的Context对象是一个更好的选择,而不仅仅是从划伤。
我认为从头开始编写它会更好。难道上下文类不会增长并向GOD对象移动。通过自己制作一个,你可以保持小。
上下文对象的替代方法是将小型服务公开给他们可以使用的插件。一个很好的方法是使用控件容器的反转来构建实现IPlugin
接口的类。
通过这种方式,他们可以直接使用依赖注入来直接获取应用程序服务(它们的合同,即接口)。
类似的东西:
//register the plugins in the container
var plugins = Directory.GetFiles(yourAppDirectory, "plugin_*.dll");
foreach (var pluginDll in plugins)
{
var assembly = Assembly.Load(pluginDll);
var pluginType = assembly.GetTypes().FirstOrDefault(x=> typeof(IPlugin).IsAssignableFrom(x));
yourContainer.RegisterType(pluginType, typeof(IPlugin));
}
最后加载它们:
var plugins = container.ResolveAll<IPlugin>();
foreach(var plugin in plugins)
plugin.Init();
然后可以将插件定义为:
public class HelpPlugin : IPlugin, IMenuHandler
{
public HelpPlugin(IMenuService service)
{
service.AddTopMenu("Help", this);
}
void IMenuHandler.Handle(MenuClick click)
{
MessageBox.Show("Menu button was clicked");
}
}
耶!不需要上下文对象。