【发布时间】:2009-10-02 19:37:19
【问题描述】:
当一个人想要实现一种简单的插件方法时,在 C# 中推荐的方法是什么?
所以基本上我有一个处理循环,我希望根据用户选择的内容发生不同的行为。假设处理代码中有两个地方的逻辑(代码)必须根据用户输入而有所不同。例如,用户可以选择基于网络或基于文件的上传。所以我真的有点想把这两个具体的方法传到处理循环中来表示
有什么建议可以在这里实现吗?
谢谢
【问题讨论】:
标签: c# plugins design-patterns
当一个人想要实现一种简单的插件方法时,在 C# 中推荐的方法是什么?
所以基本上我有一个处理循环,我希望根据用户选择的内容发生不同的行为。假设处理代码中有两个地方的逻辑(代码)必须根据用户输入而有所不同。例如,用户可以选择基于网络或基于文件的上传。所以我真的有点想把这两个具体的方法传到处理循环中来表示
有什么建议可以在这里实现吗?
谢谢
【问题讨论】:
标签: c# plugins design-patterns
您真的需要基于(传统)插件的解决方案来解决这个问题吗?就我个人而言,我不这么认为,在我看来,这听起来像是试图将真正简单问题的解决方案过度复杂化。
我处理这个问题的方法是有一个单独的服务类,它负责根据上传类型处理逻辑。有一个枚举来定义用户选择的上传类型,然后实例化服务类的相关具体实现来做处理。
公共枚举 FileUploadType { 文件, 网络 } 公共接口 IProcessingService { 无效进程(); 对象 GetResults(); // 或者任何你想对处理结果做的事情 } 公共无效进程(文件上传类型文件上传类型) { IProcessingService 服务; 开关(类型) { case FileUploadType.File: service = new FileUploadProcessingService();休息; case FileUploadType.Web: service = new WebUploadProcessingService();休息; 默认值:/* 日志错误 */ break; } 服务.进程(); /* 对处理结果做一些事情 */ }如果您决定要开始使用 IoC 容器或引入适当的插件机制,以后可以轻松地重构它。
【讨论】:
也许你应该看到控制模式反转(依赖注入),它基本上是关于在运行时解决接口的实现(用很少的话说)。
【讨论】:
其他人提到了Delegates,如果您自己控制所有代码和功能,这是最好的方法,但是,如果您真的想要基于插件系统,这样您的应用程序会公开一些 API,并且您允许第 3 方开发人员编写将加载的程序集(通常是 DLL)以及您的应用程序使用的功能,您可以使用多种方法。
一般方法是您的应用程序(宿主应用程序)将发布/公开具有特定接口的程序集。其他开发人员将编写他们的程序集并确保他们的类实现您的应用程序的接口。然后,宿主应用程序通常会枚举包含“插件”程序集的文件夹,并找到定义实现其接口的类的程序集。然后宿主应用程序将动态加载这些程序集并实例化这些类。
可以在此处找到有关此通用方法的优秀教程:
Managed Extensibility Framework 也是通用插件架构的另一种选择,但对于您想要实现的目标可能有点过头了。
【讨论】:
代表。
delegate void DoSomething1(int x, double y);
delegate int DoSomething2(string s);
void MainWork(DoSomething1 something1, DoSomething2 something2)
{
}
并且在调用MainWork()时,可以插入一些合适的方法。
void Do1(int x, double y) { }
int Do2(string s) { }
MainWork(Do1, Do2);
【讨论】:
你看过微软的Managed Extensibility Framework吗?
从简介:
托管可扩展性框架 (MEF) 是 .NET 中的一个新库,可以更好地重用应用程序和组件。使用 MEF,.NET 应用程序可以从静态编译转变为动态组合。如果您正在构建可扩展应用程序、可扩展框架和应用程序扩展,那么 MEF 适合您。
【讨论】:
您可以使用委托或部分方法来挂钩您的代码,但这意味着必须重新编译程序集。
【讨论】:
if 有什么问题?
这样的事情不会更简单吗?
if (IsCase1(userInput))
{
... do case 1 actions
}
else
{
... do case2 actions
}
我不会让事情变得过于复杂。这里的关键是¿有必要吗?如果您确实需要将功能作为参数传递,我会使用 Delegates 解决方案(下一个更简单的解决方案),并且仅将插件作为最后的手段。
记住 KISS 原则!
【讨论】: