代码之家  ›  专栏  ›  技术社区  ›  clicky

Unity静态特性注入

  •  6
  • clicky  · 技术社区  · 11 年前

    我有两个类,一个类通过注册类型来设置容器,另一个类包含我要注入的静态属性。我的问题是,该属性从不通过注入设置,所以当我对其调用方法时,该属性始终为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中为ClassTwo添加了RegisterType和Resolve,还添加了InjectionProperty:

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

    但它仍然不起作用:S

    2 回复  |  直到 11 年前
        1
  •  7
  •   Community Mofi    7 年前

    经考虑意见后编辑:

    有时您仍然希望或需要使用静态类,而不是通过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>();
    
        2
  •  6
  •   jlvaquero    11 年前

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

    使用Unity来解析伪单例类,而不是使用静态类( ContainerControlledLifetimeManager )第二类。Unity通过这种方式注入 IClass ClassTwo 什么时候 第二类 被创建(通过Unity容器解析),并且,由于被配置为singleton,您总是有相同的 第二类 在应用程序的整个生命周期中。

    你必须通过团结来解决第二类问题。

    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的魔力,它依赖于注入级联。当两个类(顶层或非顶层)需要使用的相同实例时 第二类 如果你配置了Unity,那就做脏活 第二类 具有 ContainerControlledLife管理器 .

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

    推荐文章