【问题标题】:How to configure the LifeStyle based on a marker interface如何基于标记界面配置 LifeStyle
【发布时间】: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&lt;TCommand&gt; 接口,它指定实现不必是线程安全的。在配置容器时,我们知道我们不能将命令处理程序配置为单例。
  • 我同意史蒂文的观点,这是个坏主意。
  • 史蒂文,我想要实现的是形成你刚刚给出的那种规则作为例子:“一个 IHandler 不能是单例的”。但我希望它在代码中完成,这样我就可以构建一个完全自动的组件注册。我正是为此创建了标记界面。我知道这听起来可能很奇怪,但我使用 Ioc 只是为了在使用大量接口的同时将事物连接在一起。对于给定的服务,我不需要能够从一种实现切换到另一种实现(因此我不需要外部 DI 配置)。

标签: c# .net castle-windsor ioc-container


【解决方案1】:

您可以根据实现的接口使用 Where() 过滤组件

            container.Register
            (
                AllTypes.FromThisAssembly()
                .Where(c=> c.GetInterface(typeof(LifestyleUponInterface.InterfaceForSingleton).Name)!=null )
                .Configure( c=> c.LifeStyle.Singleton )
            );
            container.Register
            (
                AllTypes.FromThisAssembly()
                .Where(c => c.GetInterface(typeof(LifestyleUponInterface.InterfaceForTransient).Name) != null)
                //.If(Component.IsInNamespace("<yourNamespace>"))
                .Configure(c => c.LifeStyle.Transient)
            );

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-10
    • 1970-01-01
    • 2011-02-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多