C# 统一静态特性注入

C# 统一静态特性注入,c#,unity-container,containers,dependency-properties,property-injection,C#,Unity Container,Containers,Dependency Properties,Property Injection,我有两个类,一个通过注册类型来设置容器,另一个包含我想要注入的静态属性。我的问题是这个属性从来都不是通过注入设置的,所以当我对它调用一个方法时,这个属性总是空的 public class ClassOne { public void Method() { Container.RegisterType<IClass, ClassImplOne>("ImplOne"); Container.RegisterType<IClass, C

我有两个类,一个通过注册类型来设置容器,另一个包含我想要注入的静态属性。我的问题是这个属性从来都不是通过注入设置的,所以当我对它调用一个方法时,这个属性总是空的

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();
    }
}
公共类一
{
公开作废法()
{
Container.RegisterType(“ImplOne”);
Container.RegisterType(“ImplTwo”);
}
}
公共静态类2
{
[依赖性]
公共静态IClass SomeProperty{get;set;}
公共静态void SomeOtherMethod()
{
SomeProperty.AnotherMethod();
}
}
如果我删除Dependency属性并在ClassOne中执行一个简单的

ClassTwo.SomeProperty = Container.Resolve<IClass>("ImplOne");
ClassTwo.SomeProperty=Container.Resolve(“ImplOne”);
它工作得很好,但我想知道是否可以在不显式地为属性指定值的情况下执行此操作(即,容器是否可以通过属性进行注入)

编辑:

谢谢。我已从Class2中删除了静态声明,并在ClassOne中为Class2添加了RegisterType和Resolve,还添加了InjectionProperty:

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

但是它仍然不起作用:当类通过Unity解析时,Unity注入依赖项。无法创建静态类,因此Unity无法注入依赖项

不要使用静态类,而是使用Unity解析Class2的伪单例类(
ContainerControlled LifetimeManager
)。这样,当创建
ClassTwo
时(通过Unity容器解析),Unity将
IClass
注入到
ClassTwo
,并且,由于配置为singleton,在应用程序的整个生命周期中,始终具有相同的
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.
但这不是一个很好的解决方案,我认为你的问题在于DI的系统哲学。您需要从应用程序的顶层类级联依赖项。以显式方式解析顶层类。(
Container.Resolve
)和依赖项注入由于统一的魔力而层叠而下。当两个类(顶层或非顶层)需要使用相同的
ClassTwo
Unity实例时,如果您使用
containerControlled LifetimeManager
配置
ClassTwo
,则执行脏工作


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

在考虑注释后编辑:

有时您仍然希望或需要使用静态类,而不是通过统一级联所有内容,原因有很多

如果静态类依赖于另一个类,而您希望通过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();
    }

}
公共静态类二
{
私有静态IClass_someProperty;
公共静态Func ResolveProperty{private get;set;}
私有静态IClass属性
{
获取{return someProperty???(someProperty=ResolveProperty());}
}
公共静态void SomeOtherMethod()
{
SomeProperty.AnotherMethod();
}
}
在Unity配置中添加以下内容:

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

将我的答案编辑得更具体一些。谢谢,我已经复制了你说的内容,但仍然不起作用。Class2是静态的,只是因为所有的组件都是静态的,因为它们通过ExcelDNA和XML绑定到Excel和Office功能区。我已经从类中删除了static关键字,注册了Class2,并在注册ClassImplOne后解决了它,但属性仍然为空。Unity将只注入实例属性-您还需要将static从属性声明中移除。很抱歉复制/粘贴代码时出错,Chris是对的。删除类中的所有静态声明。我将编辑我的答案,因为代码与文本相矛盾。
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();
    }

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