繁体   English   中英

结合使用MEF和依赖注入

[英]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标记它们可以在程序中使用这些实例。

您只应实例化该类一次。 在这个例子中,我们在启动时在主程序块中实例化它。

我们已将ContainerILogger都标记为导出,因为我们希望这些实例可用于其他依赖类。

导出IService

用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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM