我有一个基类Class Base,它具有dependecy Dep和default and Injection Constructor -
Class Base : IBase
{
public IDep Dep { get; set; }
public Base()
{
Console.WriteLine("Default Constructor Base ");
}
[InjectionConstructor]
public Base(IDep dep)
{
Console.WriteLine("Injection Constructor Base ");
Dep = dep;
}
}
我认为在解析派生类时,应该自动注入Dependency dep(通过Constructor Injection)。
但是当我从它派生一个类并解析该类时,这似乎不起作用,而是调用Base的默认构造函数。
当我从Derived Class中显式调用构造函数时,我才能使它工作。
class Derived : Base
{
public Derived ()
{
Console.WriteLine("Default Constructor Derived ");
}
public Derived (IDep dep) : base(dep1)
{
Console.WriteLine("Injection Constructor Derived ");
}
}
unity是否提供了任何直接的方法来隐式调用基类的注入构造函数(而不是通过显式的Construtor调用)? 如果没有,是否有任何理由说明为什么统一容器本身没有做到?
答案 0 :(得分:16)
不,团结是无法做到的。实际上,没有一个容器可以这样做。 构造函数用于实例化一个类。如果你调用两个构造函数,最终会得到两个实例。如果基类是抽象的,你甚至无法调用它的构造函数(除了你知道的派生构造函数)。
因此,通过C#.net的限制,如果要使用构造函数注入,只有在将值显式注入调用非默认Derived
构造函数的Base
构造函数时,它才会起作用。
但是,您可以选择使用Property或Method注入。使用这些,您不必将依赖项添加到派生类的每个构造函数。
<强> Property Injection 强>:
class Base
{
[Dependency]
public IDep Dep { get; set; }
}
<强> Method Injection 强>:
class Base
{
private IDep dep;
[InjectionMethod]
public void Initialize(IDep dep)
{
this.dep = dep;
}
}
请注意:
答案 1 :(得分:5)
这就是解决问题的方法:
class abstract Base : IBase
{
private readonly IDep dep;
protected Base(IDep dep)
{
if (dep == null) throw new ArgumentNullException("dep");
this.dep = dep;
}
}
现在你的基类只有一个构造函数,这个构造函数定义了类所需的所有依赖项。只有一种方法可以创建这个类,该类将保护其不变量。依赖项位于私有字段中,因为其他类在访问此依赖项时没有用处。
使用此基类,派生类将如下所示:
class Derived : Base
{
private readonly IDep dep;
public Derived(IDep dep) : base(dep)
{
this.dep = dep;
}
}
此处派生类还有一个构造函数,用于定义此类所需的依赖项。它不能以不同的方式创建。如果类使用依赖项本身,它应该将依赖项存储在私有字段中供以后使用。另请注意,因为此类只有一个构造函数,所以要调用的构造函数没有歧义,并且没有理由使用[InjectionConstructor]属性标记构造函数。
请注意我同意BatteryBackupUnit。由于我将依赖注入和SOLID原则应用于我的应用程序,因此我认为没有理由再使用基类了。使用Composition而不是继承通常会降低系统的复杂性。
答案 2 :(得分:0)
简单直接的解决方案是拥有一个&#34; InjectionMethod&#34;在您的基础课程中。
> public abstract class Base : IBase
> {
>
> private IDep dep;
>
> [InjectionMethod]
> public void Initialize(IDep dep)
> {
> if (dep == null) throw new ArgumentNullException("dep");
> this.dep = dep;
>
> OnInitialize();
> }
>
> public dep DepProperty
> {
> get
> {
> return dep;
> }
> }
> protected abstract void OnInitialize();
> }
//现在你的Derived类构造函数不会被强制拥有IDep参数
class Derived : Base
{
public Derived()
{
}
protected override void OnInitialize()
{
// you can access the baseclass dependency Instance in this override
object depObject = this.DepProperty;
}
}