5

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

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 中为 ClassTwo 添加了 RegisterType 和 Resolve,还添加了 InjectionProperty:

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

但它仍然不起作用:S

4

2 回答 2

7

考虑评论后编辑:

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

如果静态类依赖于您希望通过 Unity 配置可配置/可交换的另一个类,我更喜欢使用工厂模式,如如何使用 Unity 解决静态类中的依赖项?或者只是在需要时分配一个函数来解决依赖关系,而不是从静态类中引用容器。一个优点是您的所有 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>();
于 2016-03-18T10:39:56.580 回答
6

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

不用静态类,而是使用 Unity 来解析ContainerControlledLifetimeManagerClassTwo 的伪单例类 ()。通过这种方式 Unity 注入IClassClassTwo何时ClassTwo创建(通过 Unity 容器解决),并且配置为单例,您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 的哲学。您需要从应用程序的顶层类级联依赖项。以显式方式解析顶层类。( Container.Resolve) 和依赖注入级联,这要归功于 Unity 的魔力。如果ClassTwoClassTwo使用ContainerControlledLifetimeManager.

换句话说,您不需要静态类,您将相同的类实例注入到其他类中而不是需要它。

于 2013-02-28T12:11:00.867 回答