[英]Using MEF with dependency injection
我有一个使用记录器类型的依赖注入实例化的类,如下所示:
var _logger = Logger.GetLogger(LoggerType.MongoLogger);
var service = new MyService(_logger);
在单元测试中,我替换记录器以使用:
var _logger = Logger.GetLogger(LoggerType.TextFileLogger);
现在,我想使用MEF将MyService作为插件加载,我这样创建了服务:
[Export(typeof(IService))]
public class MyService: IService
{
private ILogger _logger;
public MyService(ILogger logger)
{
this._logger = logger;
}
public void DoServiceWork()
{
_logger.Log("Starting service work");
}
}
我该如何在MEF框架中使用此工具?
编辑:使用控制台应用程序添加了更详细的示例。
此类创建MEF容器并初始化聚合目录。 您还应该实例化其他可导出项,例如ILogger,程序中的其他依赖类将使用这些可导出项。 创建属性并用Export
标记它们可以在程序中使用这些实例。
您只应实例化该类一次。 在这个例子中,我们在启动时在主程序块中实例化它。
我们已将Container
和ILogger
都标记为导出,因为我们希望这些实例可用于其他依赖类。
用Export(IService)标记MySerivce类可使其在MEF中导出。 我们使用MEF通过调用Container.GetExportedValue<IService>();
来获取它的实例Container.GetExportedValue<IService>();
。 注意:默认情况下,MEF将使用单例共享实例,即对象将创建一次。 如果要使用非共享实例,则必须使用PartCreationPolicy(CreationPolicy.NonShared)
标记类。
using System.ComponentModel.Composition.Hosting;
using System.ComponentModel.Composition;
class Program
{
static void Main(string[] args)
{
var bootstrap = new Bootstrap();
var service = bootstrap.Container.GetExportedValue<IService>();
service.DoServiceWork();
}
}
public class Bootstrap
{
[Export]
public CompositionContainer Container { get; private set; }
[Export(typeof(ILogger))]
public ILogger Logger { get; private set; }
public Bootstrap()
{
//Create an aggregate catalog that will hold assembly references
var catalog = new AggregateCatalog();
//Adds this assembly.
//Exports defined in the classes and types within this assembly will now be composable
//Add to the catalogs if there are more assemblies where exports are defined.
catalog.Catalogs.Add(new AssemblyCatalog(Assembly.GetExecutingAssembly()));
//Create the CompositionContainer with the parts in the catalog
this.Container = new CompositionContainer(catalog);
this.Logger = Logger.GetLogger(LoggerType.MongoLogger);
this.Container.ComposeParts(this);
}
}
[Export(typeof(IService))]
public class MyService : IService
{
//adding pragma directive removes compiler warning of unassigned property/field
//as these will be assigned by MEF import
#pragma warning disable
[Import]
private ILogger _logger;
#pragma warning restore
public MyService()
{
//logger will be instantiated by MEF
}
public void DoServiceWork()
{
_logger.Log("Starting service work");
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.