我有两个类,一个通过注册类型来设置容器,另一个包含我要注入的静态属性。我的问题是属性永远不会通过注入设置,因此当我在其上调用方法时,属性始终为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
答案 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
,则会执行脏工作。
换句话说,你不需要静态类,你可以在其他类中注入相同的类实例。