简体   繁体   English

如何使用类库设置mef?

[英]How do I setup mef with a class library?

I've recently started using MEF in my application, and have had no issues using it or testing classes that it acts upon inside of my main application; 我最近开始在我的应用程序中使用MEF,并且在使用它或测试它在我的主应用程序中作用的类方面没有问题。 however, I'm just now starting to create a licensing library for my application, have run into some issues, since I'm unsure of how to set it up. 但是,由于我不确定如何设置它,所以我现在刚刚开始为我的应用程序创建许可库,但是遇到了一些问题。

In my licensing library, I've got LicenseManager, LicenseValidator, and LicenseSigner classes: 在我的许可库中,我有LicenseManager,LicenseValidator和LicenseSigner类:

public class LicenseManager
{
    [Import]
    private ILicenseValidator _validator;

    [Import]
    private ILicenseSigner _signer;

    public LicenseManager()
    {
        var catalog = new AssemblyCatalog(System.Reflection.Assembly.GetExecutingAssembly());
        var container = new CompsitionContainer();
        container.ComposeParts();
    }
}

[Export(typeof(ILicenseSigner))]
public class LicenseSigner : ILicenseSigner
{
    ...
}

[Export(typeof(ILicenseValidator))]
public class LicenseValidator : ILicenseValidator
{
    ...
}

I find that both the validater and the signer are null after accessing them. 访问它们后,我发现验证者和签名者均为null

Which I assume is due to the fact that I'm instantiating LicenseManager before the constructor for LicenseManager can create the container; 我认为是由于我在LicenseManager的构造函数创建容器之前实例化了LicenseManager。 however, I'm not entirely sure how to solve the problem, since LicenseManager is intended as the only entry point into the class library. 但是,我不确定如何解决该问题,因为LicenseManager旨在用作类库的唯一入口点。 I could possibly create some sort of factory to initialize the container and return a LicenseManager instance, but that would result in a less nice library API. 我可能会创建某种工厂来初始化容器并返回LicenseManager实例,但这会导致不太好的库API。

I'm sort of new to the whole MEF thing. 我对整个MEF有点陌生。 Is there something I could be doing better? 有什么我可以做得更好的吗? Is there a way for me to take care of all the MEF loading in my main application? 我有办法照顾我的主应用程序中的所有MEF加载吗? Any solution is better than the lack of one that I have now. 任何解决方案都比我现在缺乏解决方案要好。

The ComposeParts call needs at least one attributed object to compose. ComposeParts调用至少需要一个属性对象才能组成。 You should pass in the LicenseManager as the argument to ComposeParts . 你应该在传递LicenseManager作为参数ComposeParts So, your full set of code would look like: 因此,您的全套代码如下所示:

public class LicenseManager
{
    [Import]
    private ILicenseValidator _validator;

    [Import]
    private ILicenseSigner _signer;

    public LicenseManager()
    {
        var catalog = new AssemblyCatalog(System.Reflection.Assembly.GetExecutingAssembly());
        var container = new CompsitionContainer(catalog);
        container.ComposeParts(this);
    }
}

[Export(typeof(ILicenseSigner))]
public class LicenseSigner : ILicenseSigner
{
    ...
}

[Export(typeof(ILicenseValidator))]
public class LicenseValidator : ILicenseValidator
{
    ...
}

In my testing, the above code worked. 在我的测试中,以上代码有效。

Another idea would be to delegate the choosing of the catalogs to the code implementing the library. 另一个想法是将目录的选择委托给实现该库的代码。 Your constructor would become: 您的构造函数将变为:

public LicenseManager(AggregateCatalog catalog)
{
    var container = new CompsitionContainer(catalog);
    container.ComposeParts(this);
}

This allows the program implementing your licensing library to specify where the exports will come from. 这使实现您的许可库的程序可以指定导出的来源。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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