我发现在 CaSTLeWindsor DI 中,您可以很容易地陷入一种情况,即有关以不同生活方式注册的依赖组件。
假设我们有以下类和接口(interface):
public class MyThing : IMyThing
{
public MyThing()
{
}
}
public interface IMyThing {}
这是在相关的 Windsor 安装程序中注册的,其中还包括 HttpContextBase 的注册:
container.Register(
Component
.For<IMyThing>()
.ImplementedBy<MyThing>()
.LifeStyle.Singleton);
container.Register(
Component
.For<HttpContextBase>()
.UsingFactoryMethod(_ => new HttpContextWrapper (HttpContext.Current) )
.LifestylePerWebRequest());
一切都很好。但是现在一些开发人员决定 MyThing 现在依赖于 HttpContext 中的某些东西,所以他更改 MyThing 以接受 HttpContextBase:
public class MyThing : IMyThing
{
private readonly HttpContextBase _httpContext;
public MyThing(HttpContextBase httpContext)
{
_httpContext = httpContext;
}
}
从表面上看,这似乎很合理 - 毕竟,在设计您的类时,您应该能够做到这一点而无需过多考虑依赖项注入(inject)的细节。然而,实际上,我们现在有一个微妙(但可能很严重)的错误,即一个组件依赖于另一个生命周期比自身短的组件。
现在,我原以为这会在 CaSTLe Windsor 中抛出某种异常,但似乎并没有。它会非常高兴地为您提供一个 MyThing,其中包含当时碰巧是当前 HttpContext 的任何内容,并且将在应用程序的剩余生命周期中继续为您提供相同的对象具有相同的 HttpContext。
谷歌搜索后,我无法找到任何 Windsor 配置来解决这个问题。有人对此有什么建议吗?我所从事的项目绝对是 DI 设置的狗晚餐,事实证明发现此类问题非常困难(在我给出的示例中,如果 Controller 的 HttpContext 错误,应该会很明显,但在其他情况下可能要少得多)。
最佳答案
CaSTLe Windsor 不会为此抛出异常,但会在调试器中将其显示为警告。 (在新标签页中打开图片)
下面是一个可以显示它的测试:
[TestFixture]
public class WindsorTests
{
[Test]
public void LifecycleWarningTest()
{
IWindsorContainer container = new WindsorContainer();
container.Register(
Component.For<ISingleton>().ImplementedBy<Singleton>().LifestyleSingleton(),
Component.For<ITransient>().ImplementedBy<Transient>().LifestyleTransient()
);
ISingleton singleton = container.Resolve<ISingleton>();
}
}
interface ISingleton
{
}
class Singleton : ISingleton
{
private readonly ITransient _transient;
public Singleton(ITransient transient)
{
_transient = transient;
}
}
interface ITransient
{
}
class Transient : ITransient
{
}
关于c# - 温莎城堡 : How to detect registrations with a longer lifetime than their dependencies?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22327777/