Unity静态属性注入

时间:2013-02-28 11:40:18

标签: c# unity-container containers dependency-properties property-injection

我有两个类,一个通过注册类型来设置容器,另一个包含我要注入的静态属性。我的问题是属性永远不会通过注入设置,因此当我在其上调用方法时,属性始终为null。

public class ClassOne
{
    public void Method()
    {
        Container.RegisterType<IClass, ClassImplOne>("ImplOne");
        Container.RegisterType<IClass, ClassImplTwo>("ImplTwo");
    }
}

public static class ClassTwo
{
    [Dependency]
    public static IClass SomeProperty { get; set; }

    public static void SomeOtherMethod()
    {
        SomeProperty.AnotherMethod();
    }
}

如果我删除了Dependency属性,并在ClassOne中做了一个简单的

ClassTwo.SomeProperty = Container.Resolve<IClass>("ImplOne");

它工作正常,但我想知道是否可以在没有明确为属性赋值的情况下执行此操作(即容器是否可以通过属性注入)?

编辑:

感谢。我已经从ClassTwo中删除了静态声明,并在ClassOne中添加了RegisterType和Resolve for ClassTwo,并且还添加了InjectionProperty:

Container.RegisterType<IClass, ClassImplOne>("ImplOne", new InjectionProperty("SomeProperty"));

但它仍然不起作用:S

2 个答案:

答案 0 :(得分:6)

在考虑评论后编辑:

有多种原因导致您仍然需要或者需要使用静态类而不是通过Unity级联所有内容。

如果静态类依赖于您希望通过Unity配置进行配置/交换的另一个类,我更喜欢使用How to resolve dependency in static class with Unity?中描述的工厂模式,或者只是分配一个函数来解决依赖关系。需要,而不是从静态类中引用Container。一个优点是所有Unity配置都可以在同一个地方。

在您的情况下,它可能如下所示:

public static class ClassTwo
{
    private static IClass _someProperty;

    public static Func<IClass> ResolveProperty { private get; set; }

    private static IClass SomeProperty
    {
        get { return _someProperty ?? (_someProperty = ResolveProperty()); }
    }

    public static void SomeOtherMethod()
    {
        SomeProperty.AnotherMethod();
    }

}

在Unity配置中添加以下内容:

ClassTwo.ResolveProperty = () => container.Resolve<IClass>();

答案 1 :(得分:5)

Unity通过Unity解析类时注入依赖关系。无法创建静态类,因此Unity无法注入依赖项。

使用Unity来解析ClassTwo的伪单例类(ContainerControlledLifetimeManager),而不是使用Static类。这样,Unity会在创建IClass时向ClassTwo注入ClassTwo(通过Unity容器解析),并且,如配置为singleton,您始终具有相同的ClassTwo实例你申请的整个生命周期。

您必须通过Unity解决ClassTwo。

Container.RegisterType<IClass, ClassImplOne>("ImplOne");
Container.RegisterType<IClass, ClassImplTwo>("ImplTwo");
Container.RegisterType<InterfaceImplemetedByClassTwo, ClassTwo>();

//Simple example. Don't forget to use ContainerControlledLifetimeManager for ClassTwo to simulate sigleton.

当你需要ClassTwo时:

Container.Resolve<InterfaceImplemetedByClassTwo>

在ClassTwo中配置:

public class ClassTwo : InterfaceImplemetedByClassTwo
{
    [Dependency("ImplOne")] //inject ClassImplOne
    public IClass SomeProperty { get; set; }

但这不是一个很好的解决方案,我认为你的问题在于DI的哲学。您需要从应用程序的顶层类级联依赖关系。以显式方式解析顶层类。由于Unity的魔力,(Container.Resolve)和dependecies注入级联。当2个类(顶层或非顶层)需要使用ClassTwo Unity的同一个实例时,如果您使用ClassTwo配置ContainerControlledLifetimeManager,则会执行脏工作。

换句话说,你不需要静态类,你可以在其他类中注入相同的类实例。