【问题标题】:SimpleInjector does not inject property using Implicit Property InjectionSimpleInjector 不使用隐式属性注入来注入属性
【发布时间】:2012-04-23 05:54:30
【问题描述】:

我有一个ObjectA,它有一个ObjectB 的属性,它有一个ObjectC 的属性,它们都在Simple Injector 容器中。当我创建ObjectA 时,我在其上调用InjectProperties,它会加载ObjectB。但是,此时它并没有在新创建的ObjectB 中加载对ObjectC 的引用;它不会执行我所说的对象“深度堆积”。

有没有办法启用它?

编辑

我有一个类对象 A:

public class ObjectA
{
     public ObjectB InstanceB { get; set; }
}

其中有ObjectB的属性:

public class ObjectB
{
     public ObjectC InstanceC { get; set; }
}

所有都已使用容器上的标准注册方法注册。为了获得ObjectA,我使用GetInstance<ObjectA>(),,这很好,我还构建了一个初始化器来在创建时构建所有对象:

_container.RegisterInitializer<object>(i => _container.InjectProperties(i));

这会将ObjectB 注入ObjectA,但不会在解析ObjectB 时将ObjectC 注入ObjectB

有解决方法吗?谢谢。

【问题讨论】:

  • Simple Injector 系统应该开箱即用地构建您的整个树,您能否发布示例代码,包括容器注册。您可能需要考虑使用构造函数注入,而不是在构造后显式注入属性。如果您无法更改此模式,您可能需要考虑使用不同的 IoC 容器,例如 Unity。这绝对支持后期构建深度构建
  • 请出示这些课程的代码和注册。我同意罗伯特所说的大多数人的观点,除了切换到 Unity(尤其是 Unity)。

标签: .net dependency-injection ioc-container simple-injector


【解决方案1】:

我使用您的代码和配置编写了一个小测试(并添加了缺少的ObjectC):

public class ObjectA
{
    public ObjectB InstanceB { get; set; }
}

public class ObjectB
{
    public ObjectC InstanceC { get; set; }
}

public class ObjectC
{

}

测试:

[TestMethod]
public void ImplicitPropertyInjectionTest()
{
    // Arrange
    var container = new Container();

    container.RegisterInitializer<object>(
        i => container.InjectProperties(i));

    // Act
    var a = container.GetInstance<ObjectA>();

    // Assert
    Assert.IsNotNull(a.InstanceB);
    Assert.IsNotNull(a.InstanceB.InstanceC);
}

测试成功,InstanceC 被正确注入。我预计您的配置有问题,或者可能无法创建 ClassC。尝试直接请求ClassC,找出容器无法创建的原因:

container.GetInstance<ClassC>();

这条线可能会失败,这就是InstanceC没有注入的原因。

这直接让我想到了以下几点:

像你一样调用RegisterInitializer&lt;object&gt;(instance =&gt; container.InjectProperties(instance)),是启用隐式属性注入的有效方法,但你应该尽可能避免使用隐式属性注入,因为这会导致无法验证容器配置(通过使用@例如 987654332@)。您已经注意到这一点,因为 InstanceC 被跳过了。相反,您应该尽可能使用构造函数注入。查看有关以可验证的方式编写代码的更多信息here

如果在某些场景下无法使用构造函数注入,最好使用显式属性注入,具体做法如下:

container.RegisterInitializer<ClassA>(a =>
{
    a.InstanceB = container.GetInstance<ClassB>();
});

container.RegisterInitializer<ClassB>(b =>
{
    b.InstanceC = container.GetInstance<ClassC>();
});

这会显式注入属性InstanceBInstanceC,当属性无法注入时会导致构造失败。

有关使用 Simple Injector 进行属性注入的更多信息,请参阅 here

最后一点。请注意,在隐式属性注入方面,所​​有容器的行为大致相同。因此,这并不是 Simple Injector 特有的。如果该容器支持此功能,它将跳过每个无法注入的属性。换句话说,所有容器都会默默地失败并继续,这通常不是你想要的。这意味着在使用默认启用隐式属性注入的容器时必须格外小心。

【讨论】:

    猜你喜欢
    • 2014-12-13
    • 2014-11-02
    • 2010-12-27
    • 1970-01-01
    • 1970-01-01
    • 2015-06-13
    • 2013-09-17
    • 1970-01-01
    • 2011-12-01
    相关资源
    最近更新 更多