在WebApi应用程序中使用MEF和DI
本文关键字:MEF DI WebApi 应用程序 | 更新日期: 2023-09-27 18:12:53
我计划使用MEF为我的导入插件实现插件架构。这些插件将导入各种数据到数据库(如。顾客、地址、产品等)。
导入插件类是这样的:
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() {}
}
然后我有一个控制器,它首先获得所有导入插件,如下所示:
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);
}
导入插件需要引用我的Services
程序集,因为这是BL发生的地方。我在Autofac的主WebApi项目中注册了我的服务,如下所示:
builder.RegisterAssemblyTypes(assemblies)
.Where(t => t.Name.EndsWith("Service"))
.AsImplementedInterfaces()
.InstancePerRequest();
是否可以将不同的服务传递给不同的导入插件?
例如,如果我要进口产品,我需要通过ProductService
,如果我要进口客户,我可能需要通过CustomerService
和AddressService
。
我如何在插件中注入这些服务(通过它们的构造函数,就像在控制器中一样)?
对于类似插件的架构,您需要三个东西:
-
契约(基本上只包含接口和简单没有提单的物品)。这将被用作插件的API。另外,这里你可以指定IImportPlugin接口
-
负责从某个文件夹或其他地方加载插件模块的模块。
-
模块,将你的插件注册为IImportPlugin。
你可以像这样在循环中注册你的插件模块:
builder.RegisterAssemblyModules(/*plugin 'Assembly' goes here*/);
在你的插件程序集中,在特定的模块中,你只指定你的插件注册:
public class MyPluginModule : Module
{
protected override void Load(ContainerBuilder builder)
{
builder.Register<ImportCustomers>().As<IImportPlugin>();
}
}
然后在插件实现ImportCustomer中,您可以使用Contract汇编中的所有内容(例如您的 iccustomerservice 接口)。如果你的系统为你的插件注册了依赖项,它将成功加载到DI容器中。