我有一个使用依赖注入记录器类型实例化的类,如下所示:
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框架中使用此功能?
答案 0 :(得分:2)
编辑: 使用控制台应用程序添加了更详细的示例。
此类创建MEF容器以及初始化聚合目录。您还应该实例化其他可导出项目,例如ILogger,由程序中的其他依赖类使用。创建属性并使用Export
标记它们允许在整个程序中使用这些实例。
您应该只实例化一次此类。在这个例子中,我们在启动时在主程序块中实例化它。
我们已将Container
和ILogger
标记为导出,因为我们希望这些实例可供其他相关类使用。
使用Export(IService)标记MySerivce类允许它在MEF中导出。我们通过调用Container.GetExportedValue<IService>();
使用MEF来获取它的实例。注意:默认情况下,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");
}
}