我最近开始在我的应用程序中使用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加载?任何解决方案都比我现有的解决方案更好。
答案 0 :(得分: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);
}
这允许实现许可库的程序指定导出的来源。