在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,如果我要进口客户,我可能需要通过CustomerServiceAddressService

我如何在插件中注入这些服务(通过它们的构造函数,就像在控制器中一样)?

在WebApi应用程序中使用MEF和DI

对于类似插件的架构,您需要三个东西:

  • 契约(基本上只包含接口和简单没有提单的物品)。这将被用作插件的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容器中。