2012-09-14 33 views
2

已经使用了温莎很长一段时间,我有点惊讶,我没有更早地遇到这个“设计”问题。我不知道如何最好地解决它。温莎城堡代码设计问题

我有一个用于执行数据转换的类ConverterService。这是接口(I已经改变了参数/返回值的对象,以简化样品): -

public interface IConverterService 
{ 
    object ConvertData(object sourceData); 
} 

转换器类需要一些配置设置,通过一个ISettingsProvider提供。这些设置用于构造函数和ConvertData()方法中。因此,我注入ISettingsProvider到构造: -

public class ConverterService : IConverterService 
{ 
    private ISettingsProvider _settingsProvider; 

    public ConverterService(ISettingsProvider settingsProvider) 
    { 
     _settingsProvider = settingsProvider; 

     // Do some one-time initialisation using info from settingsProvider 
     // and store the results in class variables (not shown), used by ConvertData. 
    } 

    public object ConvertData(object sourceData) 
    { 
     // Do the conversion - also uses _settingsProvider, 
     // and other variables initialised in the constructor .. 
    } 
} 

无论是ConverterService和SettingsProvider与温莎通常的方式注册: -

container.Register(Component.For<IConverterService>().ImplementedBy<ConverterService>().LifeStyle.Singleton); 
container.Register(Component.For<ISettingsProvider>().ImplementedBy<SettingsProvider>().LifeStyle.Singleton); 

需要使用转换器的任何类得到一个IConverterService通过它的构造函数注入 - 标准的东西。这工作正常,但我现在需要许多不同的消费者使用具有不同设置提供程序(最多两个或三个)的ConverterService的功能。

我不能让ConverterService瞬变,因为我不想每次都有初始化开销。感觉就像我需要为每种类型的ISettingProvider提供一个ConverterService的单独实例,但我不确定是否/如何使用Windsor来完成此操作,还是需要更基础的重构?

如何注册不同的设置提供程序,所有这些提供程序都实现了ISettingsProvider?更具体地说,温莎如何解决正确的问题(注意ConverterService构造函数仅仅期望一个ISettingsProvider)?

任何有关我应该如何(重新)设计类的建议将不胜感激。

回答

1

你不能为你的实例使用命名约定并以这种方式控制它们吗?因此,IConverterService的每个实例都会有一个关联的名称来指示它正在使用的配置。

此问题提供了一些关于使用命名组件/实例的信息。

Castle Windsor - How to map Named instance in constructor injection

+0

我发现这些Winsdor约定可以使代码难以理解。我想知道有不同的接口和实例,例如“FooConverterService:IFooConverterService”,“BarConverterService:IBarConverterService”等。每个具体类都会继承自“ConverterService”,它们的构造函数期望它传递给基本ctr的“IXxxSettingsProvider”。它只是意味着接口和子类的扩散(除了ctr以外是空的),但它会使代码更具可读性。 –

+0

我会说接口包装器以这种方式分组,但我不知道你是否会在编译时知道你会有什么类型,至少你可以在运行时定义它的一些名称作为它的只是字符串标识符。 – Grofit