[英]Using MEF with DI in a WebApi application
I'm planning on using MEF to implement a plugin architecture for my import plugins. 我正计划使用MEF为我的导入插件实现插件体系结构。 These plugins will import various data into the db (eg. customers, addresses, products, etc).
这些插件会将各种数据(例如,客户,地址,产品等)导入数据库。
The import plugin class looks like this: 导入插件类如下所示:
public interface IImportPlugin
{
string Name { get; }
void Import();
}
[Export(typeof(IImportPlugin))]
public class ImportCustomers : IImportPlugin
{
private readonly ICustomerService customerService;
public string Name
{
get { this.GetType().Name; }
}
public ImportCustomers(ICustomerService _customerService)
{
customerService = _customerService;
}
public void Import() {}
}
I then have a controller, which first gets all import plugins as follows: 然后,我有一个控制器,它首先获取所有导入插件,如下所示:
public IHttpActionResult GetImportPlugins()
{
var catalog = new AggregateCatalog();
catalog.Catalogs.Add(new DirectoryCatalog(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "bin")));
var directoryCatalog = new DirectoryCatalog(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Plugins"));
catalog.Catalogs.Add(directoryCatalog);
var container = new CompositionContainer(catalog);
container.ComposeParts();
var list = container.GetExportedValues<IImportPlugin>().Select(x => x.Name);
return Ok(list);
}
The import plugin needs to reference my Services
assembly because this is where the BL takes place. 导入插件需要引用我的
Services
程序集,因为这是发生BL的地方。 I register my services in the main WebApi project with Autofac as follows: 我在Autofac的主要WebApi项目中注册我的服务,如下所示:
builder.RegisterAssemblyTypes(assemblies)
.Where(t => t.Name.EndsWith("Service"))
.AsImplementedInterfaces()
.InstancePerRequest();
Is it possible to pass different services to different import plugins? 是否可以将不同的服务传递给不同的导入插件?
For example, if I'm importing products I need to pass the ProductService
, and if I'm importing customers I might need to pass CustomerService
and AddressService
. 例如,如果要导入产品,则需要传递
ProductService
,如果要导入客户,则可能需要传递CustomerService
和AddressService
。
How can I inject these services inside the plugins (through their constructors just like one would do in a controller)? 如何将这些服务注入插件中(通过它们的构造函数,就像在控制器中那样)?
For plugin-like architecture, you need three things: 对于类似插件的体系结构,您需要三件事:
Contracts (basicaly assembly containing only interfaces and simple objects withouth BL). 合同(基本程序集,仅包含接口和简单对象,而没有BL)。 This will be used as API for your plugins.
这将用作您插件的API。 Also, here you can specify IImportPlugin interface.
另外,您可以在此处指定IImportPlugin接口。
Module which responsibily will be loading plugin modules from some folder, or from somewhere else. 负责任的模块将从某个文件夹或其他位置加载插件模块。
Module in each plugin you create, to register your plugin as IImportPlugin inside DI container. 您创建的每个插件中的模块,以将插件注册为DI容器中的IImportPlugin。
You can register your plugin modules like this in loop: 您可以像这样在循环中注册插件模块:
builder.RegisterAssemblyModules(/*plugin 'Assembly' goes here*/);
In your plugin assembly, in specific module, you specify only your plugin registration: 在插件程序集中的特定模块中,您仅指定插件注册:
public class MyPluginModule : Module
{
protected override void Load(ContainerBuilder builder)
{
builder.Register<ImportCustomers>().As<IImportPlugin>();
}
}
Then in plugin implementation ImportCustomer you can use everything from Contract assembly (for example your ICustomerService interface). 然后,在插件实现ImportCustomer中,您可以使用来自Contract程序集的所有内容(例如ICustomerService接口)。 And if your system registered dependecies for your plugin - it will succesfuly load into DI container.
而且,如果您的系统为插件注册了依赖项-它将成功加载到DI容器中。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.