我正在开发 ASP.Net MVC 中的即插即用框架,我可以将模块定义为与主项目分开的项目。因此,开发人员可以根据需要创建任意数量的模块。
我需要的是能够更新任何此类模块的设置。为此,在主项目中,我为一些常用设置定义了一个基类,并且每个模块都有自己的自定义设置。当对模块进行任何编辑时,我必须在主项目中实例化该模块的实例。但是,主项目不知道任何模块。
我如何实现这一目标?
谢谢!
我正在开发 ASP.Net MVC 中的即插即用框架,我可以将模块定义为与主项目分开的项目。因此,开发人员可以根据需要创建任意数量的模块。
我需要的是能够更新任何此类模块的设置。为此,在主项目中,我为一些常用设置定义了一个基类,并且每个模块都有自己的自定义设置。当对模块进行任何编辑时,我必须在主项目中实例化该模块的实例。但是,主项目不知道任何模块。
我如何实现这一目标?
谢谢!
根据您的需要,您必须创建一个依赖于接口的解决方案。
本质上,该应用程序公开了一个 API dll,其接口名为 IModule。IModule 有一种称为 Run() 的方法。您的主应用程序将加载模块的程序集,寻找实现 IModule 的东西,创建其中一个对象并在其上调用 Run()。
这是一篇旧文章,描述了如何托管沙箱以在其中运行模块。 http://msdn.microsoft.com/en-us/magazine/cc163701.aspx
namespace MyApplication.Api
{
public interface IModule
{
void Run();
}
}
开发人员会创建这样的东西
public class MyObject : MarshalByRefObject, IModule
{
public void Run()
{
// do something here
}
}
该应用程序将使用某种反射加载它。
public void LoadModule()
{
var asm = System.Reflection.Assembly.Load(/* Get the developer module name from somewhere*/);
var types = asm.GetExportedTypes();
foreach(var t in types)
{
foreach(var i = t.GetInterfaces())
{
if(i == typeof(IModule))
{
var iModule = System.Activator.CreateInstance(t);
iModule.Run();
}
}
}
}
最好在另一个 appDomain 中运行代码,但这会增加很多复杂性。
public void LoadModuleInAppDomain()
{
// Spin up a new AppDomain
// Load the assembly into the app domain
// Get the object
// Call the Run Method
}
您可以使用依赖注入并将这些模块注入到您的应用程序的组合根目录中。根据配置,您可以使用代码或 xml(配置文件)。您可以根据您的实际需要进行自动接线、后期绑定等。
您还可以在每个模块上都有初始化程序,因此每当您注册一个模块时,它应该初始化您注册的模块并注入依赖项等。