5

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

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

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

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

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

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

4

1 回答 1

13

暂时忽略 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) { }
}

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

就使用属性注入与构造函数注入而言:最好将类型初始化为可用状态。在构造函数中应该需要任何显式依赖项。但是,因为 MEF 将满足所有导入,所以当您从容器中取回您的部分时,构造函数和属性注入都已经发生,因此您可以使用属性导入来代替。我的偏好一直是使用构造函数导入。

于 2012-04-21T08:49:01.903 回答