0

我最近开始在我的应用程序中使用 MEF,并且在使用它或测试它在我的主应用程序内部起作用的类时没有遇到任何问题;但是,我刚刚开始为我的应用程序创建一个许可库,遇到了一些问题,因为我不确定如何设置它。

在我的许可库中,我有 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
{
    ...
}

我发现验证者和签名者都null在访问它们之后。

我认为这是因为我在 LicenseManager 的构造函数创建容器之前实例化了 LicenseManager;但是,我不完全确定如何解决该问题,因为 LicenseManager 旨在作为类库的唯一入口点。我可能会创建某种工厂来初始化容器并返回一个 LicenseManager 实例,但这会导致库 API 不太好。

我对整个 MEF 有点陌生。有什么我可以做得更好的吗?有没有办法让我在我的主应用程序中处理所有 MEF 加载?任何解决方案都比我现在缺少的解决方案要好。

4

1 回答 1

1

ComposeParts调用需要至少一个属性对象来组合。您应该将LicenseManager作为参数传递给ComposeParts. 因此,您的全套代码如下所示:

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
{
    ...
}

在我的测试中,上面的代码有效。

另一个想法是将目录的选择委托给实现库的代码。您的构造函数将变为:

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

这允许实现您的许可库的程序指定导出的来源。

于 2012-07-13T21:00:38.773 回答