解决单例属性的依赖关系

时间:2014-09-04 12:42:43

标签: c# dependency-injection castle-windsor

我们假设我有一个界面

public interface IMyInterface { }

一个将此接口公开为属性的类:

public class MyClass
{
    public IMyInterface Property { get; set; }
}

MyClass在我的Windsor容器中注册为Singleton。我想连接windsor容器,以便IMyInterface解析为MyClass实例上的属性“Property”,我可以实现如下:

container.Register(Component.For<MyClass>().ImplementedBy<MyClass>().LifeStyle.Singleton);
var myClass = container.Resolve<MyClass>();
container.Register(Component.For<IMyInterface>().Instance(myClass.Property));

但是,我更愿意让容器为我做所有解决方案,所以我不必打电话给上面的container.Resolve。有没有办法实现这个目标?

3 个答案:

答案 0 :(得分:2)

如果MyClass负责创建该实例,则无法神奇地删除IMyInterface的注册。您需要注册一些内容,但通过使用工厂代理可以使您的配置更简单,如下所示:

container.Register(Component.For<IMyInterface>() 
    .UsingFactoryMethod(() => container.Resolve<MyClass>().Property) 
    .LifeStyle.Transient);

答案 1 :(得分:0)

如果您将IMyInterface注册为单身人士,则该组件只会有一个实例;任何解决方案都将返回相同的实例。它是否来自财产不会改变分辨率

事实上,容器的这种行为让我怀疑为什么通过特定的访问器来解决这个问题很重要?在你没有提到的财产的吸气剂中是否有一些额外的过程?


关于您不想解析MyClass访问其属性的事实,如果您不做, 以检索该类的实例财产静止,你不能回避这个。

答案 2 :(得分:0)

这个IMyInterface是你实现的第三方库的接口,以便使用它吗?如果是这样,我可以得出结论IMyInterface是100%需要您的实现工作。

要记住的一个重要注意事项 - 任何遇到你的类的软件开发人员都不会知道IMyInterface是这个类的真正依赖,因为它是一个属性 - 任何人都可以在某个地方重置它。当你把你的依赖项放在ctor中时,你可以保证每个人都会注意到这是一个很难的依赖,没有它,这个类就不应该工作了。通常 - “硬”依赖性来自ctor,其他可能作为属性公开。

  

然而,为了使“活动部件”的数量保持在最低水平以使API更加可口,我很高兴牺牲一种“更纯粹”的依赖注入理念来支持更少的注册。

请记住,DI原则来自实践,可维护性和可读性必须超过适口性。如果其他人维护您的代码,则更容易在ctor中发现依赖关系,而不是作为属性。因此,适口性是一种错觉,因为你知道你的代码正在做什么(现在)。

我的建议是继续使用IMyInterface的构造函数注入,只需创建一个类型工厂并通过构造函数获取它。