ImportingConstructors&子类

时间:2012-04-20 07:58:48

标签: c# mef

我有一个抽象基类和一个派生类。我正在尝试使用MEF通过在基类中使用[ImportingConstructor]向我的WindowManager注入引用。 即

[ImportingConstructor]
public SomeViewModel(IWindowManager windowmanager) {...}

问题在于,在我添加之前,我所有的都没有param构造函数,并且派生类抱怨如果我向基类添加一个无参数构造函数,WindowManager永远不会被注入。

使用我目前有限的知识,我能想到的唯一方法是将管理器导入更改为属性导入,并且只有一个无参数的默认构造函数。这种错误,因为一般规则似乎更喜欢构造函数注入所需的依赖项,以及属性注入可选的。

我可以在我的子类中添加覆盖[ImportingConstructor],但这似乎是不必要的代码重复。

有没有更好的方法来做到这一点,即确保在创建派生类时注入我的依赖项?

1 个答案:

答案 0 :(得分:12)

暂时忽略MEF并考虑一下:

public abstract class BaseClass {
    protected BaseClass(IService service) { }
}

public class SubClass : BaseClass {
    public SubClass(IService service) : base(service) { }
}

因为基类定义了一个构造函数,所以子类必须通过为基类的构造函数提供一个参数来初始化基类。

现在,有了MEF,我认为你要做的就是:

public abstract class BaseClass {
    [ImportingConstructor]
    protected BaseClass(IService service) { }
}

[Export]
public class SubClass : BaseClass {
    public SubClass() { }
}

听起来你正试图在基类的构造函数中注入一些东西,但是你不能这样做,因为它的子类的可靠性以确保将适当的参数传递给构造函数的基类。您需要对子类进行修改:

[Export]
public class SubClass : BaseClass {
    [ImportingConstructor]
    public SubClass(IService service) : base(service) { }
}

现在子类将注入服务并将其传递给基类。

在使用Property Injection与Constructor Injection方面:最好将类型初始化为可用状态。在构造函数中应该需要任何显式依赖项。但是,因为MEF将满足所有进口,当您从容器中取回零件时,构造函数和属性注入都已经发生,因此您可能会使用属性导入。我一直倾向于使用构造函数导入。