【发布时间】:2011-05-10 12:38:05
【问题描述】:
问题:
如何使用每个组件上是否存在标记界面来配置组件的生活方式?
我的规则是:
- 如果一个组件实现了IAutoInstalledComponent,那么它必须被注册
- 如果组件实现了ISingletonComponent,那么组件的生命周期必须是Singleton
- 如果一个组件实现了 IAutoInstalledComponent 而不是 ISingletonComponent,它将具有 PerWebRequest 生活方式
我在“Configure”方法的 ConfigureDelegate 中看到了 ComponentRegistration 中的“If”方法,但无法猜测也无法获得有关如何使用它的文档。
我当前的代码:
// a marker interface which I implement on my components by convention
// just to know which components to register
public interface IAutoInstalledComponent
{
}
// a marker interface to say that the lifestyle should be Singleton
public interface ISingletonComponent : IAutoInstalledComponent
{
}
// This is my unique installer
public class AutoInstaller : IWindsorInstaller
{
public void Install(IWindsorContainer container, IConfigurationStore store)
{
container.Register(AllTypes.FromThisAssembly()
.BasedOn<IAutoInstalledComponent>()
// this is what i want to be Singleton when the component (or service) implements ISingletonComponent
.Configure(c => c.LifeStyle.PerWebRequest)
);
}
}
上下文:
好的,如果您有时间,这里是对我正在尝试做的事情的全局解释。我的目标是对当前程序集中的所有组件进行批量注册。但是由于某些组件的初始化速度非常慢(并且完全是线程安全的),因此我只想创建它们的一个实例。
提前感谢您的帮助。
【问题讨论】:
-
您不应该这样做,因为现在您正在将 DI 逻辑与您的应用程序混合。您应该尝试将它们分开。只需让您的 DI 配置进行测试。这样你就可以测试某个组件是否注册为单例。
-
实际上,在我看来,DI 逻辑不能与我的应用程序完全分离,因为我的实现会因 LifeStyle 配置而大不相同。我首先想到的是线程安全:Singleton 类的所有公共实例方法都需要是线程安全的,而 Transient 或 PerHttpRequest 可以合理地保留为非线程安全的。
-
将 DI 配置与应用程序解耦并不意味着任何配置都可以工作。有些类型是线程安全的,有些则不是。这些是关于这种类型使用的 cmets,DI 配置应该知道这些细节。例如,在我的一个应用程序中,我有一个
IHandler<TCommand>接口,它指定实现不必是线程安全的。在配置容器时,我们知道我们不能将命令处理程序配置为单例。 -
我同意史蒂文的观点,这是个坏主意。
-
史蒂文,我想要实现的是形成你刚刚给出的那种规则作为例子:“一个 IHandler
不能是单例的”。但我希望它在代码中完成,这样我就可以构建一个完全自动的组件注册。我正是为此创建了标记界面。我知道这听起来可能很奇怪,但我使用 Ioc 只是为了在使用大量接口的同时将事物连接在一起。对于给定的服务,我不需要能够从一种实现切换到另一种实现(因此我不需要外部 DI 配置)。
标签: c# .net castle-windsor ioc-container