cli*_*cky 5 c# containers dependency-properties unity-container 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();
}
}
Run Code Online (Sandbox Code Playgroud)
如果我删除Dependency属性并在ClassOne中做一个简单的
ClassTwo.SomeProperty = Container.Resolve<IClass>("ImplOne");
Run Code Online (Sandbox Code Playgroud)
它工作正常,但我想知道是否可以这样做而不明确地为属性赋值(即容器可以通过属性注入)?
编辑:
谢谢.我已经从ClassTwo中删除了静态声明,并在ClassOne中添加了RegisterType和Resolve for ClassTwo,还添加了InjectionProperty:
Container.RegisterType<IClass, ClassImplOne>("ImplOne", new InjectionProperty("SomeProperty"));
Run Code Online (Sandbox Code Playgroud)
但它仍然不起作用:S
在考虑评论后编辑:
有多种原因导致您仍然需要或者需要使用静态类而不是通过Unity级联所有内容.
如果静态类依赖于您希望通过Unity配置进行配置/交换的另一个类,我更喜欢使用如何使用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();
}
}
Run Code Online (Sandbox Code Playgroud)
在Unity配置中添加以下内容:
ClassTwo.ResolveProperty = () => container.Resolve<IClass>();
Run Code Online (Sandbox Code Playgroud)
当通过Unity解析类时,Unity会注入依赖关系.无法创建静态类,因此Unity无法注入依赖项.
而不是使用Static类,使用Unity来解析ContainerControlledLifetimeManagerClassTwo 的伪单例类().这种方式Unity注入IClass到ClassTwo何时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.
Run Code Online (Sandbox Code Playgroud)
当你需要ClassTwo时:
Container.Resolve<InterfaceImplemetedByClassTwo>
Run Code Online (Sandbox Code Playgroud)
在ClassTwo中配置:
public class ClassTwo : InterfaceImplemetedByClassTwo
{
[Dependency("ImplOne")] //inject ClassImplOne
public IClass SomeProperty { get; set; }
Run Code Online (Sandbox Code Playgroud)
但这不是一个很好的解决方案,我认为你的问题在于DI的哲学.您需要从应用程序的顶层类级联依赖关系.以显式方式解析顶层类.Container.Resolve由于Unity的魔力,()和dependecies注入级联.当2个类(顶层或非顶层)需要使用相同的ClassTwoUnity 实例时,如果配置了ClassTwo,则执行脏工作ContainerControlledLifetimeManager.
换句话说,您不需要静态类,在其他类中注入相同的类实例而不需要它.
| 归档时间: |
|
| 查看次数: |
10505 次 |
| 最近记录: |