SimpleInjector不使用Implicit Property Injection注入属性

时间:2012-04-10 22:16:46

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

我有一个ObjectA,其中包含ObjectB的属性,该属性具有ObjectC的属性,这些属性都在Simple Injector容器中。当我创建ObjectA时,我会在其上调用InjectProperties,这会加载ObjectB。但是,此时,它不会在新创建的ObjectC中加载对ObjectB的引用;它没有执行我称之为对象的“深度构建”。

有没有办法启用它?

修改

我有一个类对象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,但在结算ObjectC时不会ObjectB注入ObjectB

有解决方法吗?感谢。

1 个答案:

答案 0 :(得分:3)

我使用您的代码和配置编写了一个小测试(并添加了缺少的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<object>(instance => container.InjectProperties(instance))是启用隐式属性注入的有效方法,但是你应该尽可能避免使用隐式属性注入,因为这会导致无法验证的容器配置(通过例如,使用container.Verify()。您已经注意到了这一点,因为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特有的。如果该容器支持此功能,它将跳过无法注入的每个属性。换句话说,所有容器都将无声地失败并继续,这通常不是您想要的。这意味着在使用默认启用隐式属性注入的容器时必须格外小心。