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

时间:2016-10-12 09:51:47

标签: c# asp.net-web-api mef

我打算使用MEF为我的导入插件实现插件架构。这些插件会将各种数据导入数据库(例如客户,地址,产品等)。

导入插件类如下所示:

namespace DataModel.Repository
{
 public class ProductRepository
 {
    internal WebApiDbEntities Context;
    internal DbSet<Product> DbSet;

     public ProductRepository(WebApiDbEntities context)
    {
        this.Context = context;
        this.DbSet = context.Set<Product>();
    }

    public virtual void Insert(Product entity)
    {
        DbSet.Add(entity);
    }

}

然后我有一个控制器,它首先获得所有导入插件,如下所示:

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); } 程序集,因为这是BL发生的地方。我使用Autofac在主WebApi项目中注册我的服务,如下所示:

Services

是否可以将不同的服务传递给不同的导入插件?

例如,如果我要导入产品,我需要传递builder.RegisterAssemblyTypes(assemblies) .Where(t => t.Name.EndsWith("Service")) .AsImplementedInterfaces() .InstancePerRequest(); ,如果我要导入客户,我可能需要传递ProductServiceCustomerService

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

1 个答案:

答案 0 :(得分:0)

对于类似插件的架构,您需要三件事:

  • 合同(基本汇编仅包含接口和简单 对象没有BL)。这将用作插件的API。此外,您可以在此处指定IImportPlugin接口。

  • 负责从某个文件夹或其他地方加载插件模块的模块。

  • 您创建的每个插件中的模块,将您的插件注册为DI容器内的IImportPlugin。

您可以循环注册插件模块:

builder.RegisterAssemblyModules(/*plugin 'Assembly' goes here*/);

在插件程序集中,在特定模块中,您只需指定插件注册:

public class MyPluginModule : Module
{
    protected override void Load(ContainerBuilder builder)
    {
        builder.Register<ImportCustomers>().As<IImportPlugin>();
    }
}

然后在插件实现 ImportCustomer 中,您可以使用合同程序集中的所有内容(例如 ICustomerService 界面)。如果您的系统为您的插件注册了dependecies - 它将成功加载到DI容器中。