我有一个抽象基类和一个派生类。我正在尝试使用MEF通过在基类中使用[ImportingConstructor]向我的WindowManager注入引用。 即
[ImportingConstructor]
public SomeViewModel(IWindowManager windowmanager) {...}
问题在于,在我添加之前,我所有的都没有param构造函数,并且派生类抱怨如果我向基类添加一个无参数构造函数,WindowManager永远不会被注入。
使用我目前有限的知识,我能想到的唯一方法是将管理器导入更改为属性导入,并且只有一个无参数的默认构造函数。这种错误,因为一般规则似乎更喜欢构造函数注入所需的依赖项,以及属性注入可选的。
我可以在我的子类中添加覆盖[ImportingConstructor],但这似乎是不必要的代码重复。
有没有更好的方法来做到这一点,即确保在创建派生类时注入我的依赖项?
答案 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将满足所有进口,当您从容器中取回零件时,构造函数和属性注入都已经发生,因此您可能会使用属性导入。我一直倾向于使用构造函数导入。