3

我正在使用 MEF 组合来自多个程序集的导出类型。我正在使用一个基类,它应该ImportMany依赖于派生类中的指定。它看起来像这样:

底座组装:

public abstract class BaseClass
{
    [ImportMany(typeof(IDependency)]
    public IEnumerable<IDependency> Dependencies { get; private set; }

    protected BaseClass()
    {
        var catalog = GetCatalog();
        var container = new CompositionContainer(catalog);
        container.ComposeParts(this);
    }

    protected abstract ComposablePartCatalog GetCatalog();
}

大会 A:

[Export(typeof(BaseClass))]
public class MyA : BaseClass
{
    protected override ComposablePartCatalog GetCatalog()
    {
        return new AssemblyCatalog(Assembly.GetExecutingAssembly());
    }
}

[Export(typeof(IDependency)]
public class DependencyA1 : IDependency {}

[Export(typeof(IDependency)]
public class DependencyA2 : IDependency {}

组装 B:

[Export(typeof(BaseClass))]
public class MyB : BaseClass
{
    protected override ComposablePartCatalog GetCatalog()
    {
        return new AssemblyCatalog(Assembly.GetExecutingAssembly());
    }
}

[Export(typeof(IDependency)]
public class DependencyB1 : IDependency {}

[Export(typeof(IDependency)]
public class DependencyB2 : IDependency {}

然后我在基础程序集中编写所有内容:

static void Main(string[] args)
{
    DirectoryCatalog catalog = new DirectoryCatalog(path, "*.dll");
    var container = new CompositionContainer(catalog);
    IEnumerable<BaseClass> values = container.GetExportedValues<BaseClass>();

    // both BaseClass instances now have 4 Dependencies - from both Assemby A and Assembly B!
}

我遇到的问题是,当我使用 MEF 组合MyAandMyB时,每个都包含来自两个程序集的导出IDependency-ies!我只想MyA包含 exportDependencyA1DependencyA2,与MyB.

我知道我可能应该为此使用依赖注入容器,但我希望可以使用 MEF?

4

2 回答 2

1

在另一个作品的鼻子下做一个作品是非常讨厌的;)。

所以我会解决手动调用 container.GetExportedValues 并在构造函数中自己设置属性,这样你就可以一起摆脱 [ImportMany] 了。并且它没有在外部组合上被操纵。

HTH爱丽儿

于 2012-08-26T13:12:49.727 回答
1

您正在使用这种方法在 MEF 周围做一些奇怪的舞蹈,您实际上是在多次组合 BaseClass,这将根据最后发生的组合为您提供不同的结果。当前编写代码的方式在 Main 中发生的组合将是最后设置 ImportMany 的方式,因为这发生在构造函数调用 BaseClass 之后。与 Ariel 类似,我建议您不要在同一个对象上进行多个合成。

如果你必须用 MEF 做这样的事情,这里有几种方法我可以看到它可能工作:1)不要在构造函数中做第二个组合,而是使用IPartImportsSatisfiedNotification并在 OnImportsSatisifed 中进行第二次合成,尽管在第二次合成时要注意对该方法的第二次调用。2) 执行 Ariel 的建议,不要使用 ImportMany,而是简单地执行 GetExportedValues 以将该字段设置为其他程序集级目录。请记住,这仍然是一个很大的假设,即每个程序集只有一个派生类,否则您仍然会遇到重叠。3) 您可以将 ImportMany 移动到派生类中,并为每个派生类型导入唯一的依赖类型(即 IADependency 或 IBDendency)。4)您可以使用元数据来过滤特定派生类型的导入。

我不确定这些是否完美,但如果我要选择一个选项,我可能会选择 #4 的一些变体,并使用元数据在导入之间进行过滤。请参阅MEF 如何确定其导入的顺序?它显示了如何订购导入,但存在用于过滤它们的类似代码示例。

于 2012-08-26T19:59:50.287 回答