我打算使用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();
,如果我要导入客户,我可能需要传递ProductService
和CustomerService
。
如何在插件中注入这些服务(通过它们的构造函数就像在控制器中那样)?
答案 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容器中。