我试图在我的代码中清理一些可访问性的东西,并无意中破坏了Unity依赖注入.过了一会儿,我意识到我标记了一些我不想在我的DLL之外暴露到内部的公共属性.然后我开始得到例外.
因此,似乎在Unity中使用[Dependency]属性仅适用于公共属性.我认为这是有道理的,因为内部和私人道具对于Unity程序集是不可见的,但是除了Unity之外,拥有一堆你永远不希望任何人设置或能够设置的公共属性感觉真的很脏.
有没有办法让团结也设置内部或私人财产?
这是我希望通过的单元测试.目前只有公共道具测试通过:
[TestFixture] public class UnityFixture { [Test] public void UnityCanSetPublicDependency() { UnityContainer container = new UnityContainer(); container.RegisterType(); container.RegisterType (); var i = container.Resolve (); Assert.IsNotNull(i); Assert.IsNotNull(i.dep); } [Test] public void UnityCanSetInternalDependency() { UnityContainer container = new UnityContainer(); container.RegisterType (); container.RegisterType (); var i = container.Resolve (); Assert.IsNotNull(i); Assert.IsNotNull(i.dep); } [Test] public void UnityCanSetPrivateDependency() { UnityContainer container = new UnityContainer(); container.RegisterType (); container.RegisterType (); var i = container.Resolve (); Assert.IsNotNull(i); Assert.IsNotNull(i.depExposed); } } public class HasPublicDep { [Dependency] public TheDep dep { get; set; } } public class HasInternalDep { [Dependency] internal TheDep dep { get; set; } } public class HasPrivateDep { [Dependency] private TheDep dep { get; set; } public TheDep depExposed { get { return this.dep; } } } public class TheDep { }
更新:
我注意到调用堆栈设置传递的属性:
UnityCanSetPublicDependency() --> Microsoft.Practices.Unity.dll --> Microsoft.Practices.ObjectBuilder2.dll --> HasPublicDep.TheDep.set()
因此,为了至少使内部版本工作,我将这些添加到我的程序集的属性中:
[assembly: InternalsVisibleTo("Microsoft.Practices.Unity")] [assembly: InternalsVisibleTo("Microsoft.Practices.Unity.Configuration")] [assembly: InternalsVisibleTo("Microsoft.Practices.ObjectBuilder2")]
但是,没有变化.Unity/ObjectBuilder仍然不会设置内部属性
另一种解决方案是在将依赖项传递给类的方法中使用[InjectionMethod].
public class MyClass { private ILogger logger; [InjectionMethod] public void Init([Dependency] ILogger logger) { this.logger = logger;
...等等
并称之为:
container.BuildUp(instanceOfMyClass);
这将调用Init与unity的依赖关系.
我不知道解决这个问题......但是
:-) J
如果属性是get-only,那么使用构造函数注入而不是属性注入更有意义.
如果Unity 确实使用反射来设置私有或内部成员,那么它将受到代码访问安全性约束.具体而言,它不适用于低信任环境.
这个问题本身似乎是一种误解。
关于核心声明:
一堆除了Unity之外都不希望任何人设置或能够设置的公共属性。
您想在单元测试中设置它们,还是要如何通过依赖模拟?即使您没有单元测试,也有一个不可设置的依赖项(除了一些Unity魔术以外)是一个奇怪的主意。您是否希望代码非常依赖支持工具?
而且,拥有公共属性根本不是问题,因为您的代码必须取决于接口,而不取决于实现(SOLID原理之一)。如果您不遵循此原则,则没有理由使用Unity。当然,您不会在接口中声明依赖项,因此使用类不了解它们。
您已经被告知使用构造函数注入更好,但是属性注入也有其美。它允许以更少的修改添加新的依赖项(特别是,您可以完全避免更改现有的单元测试,而仅添加新的)。