2011-08-19 31 views
5

如果您考虑在类中使用Properties.Settings.Default作为依赖项,并因此注入它?对Properties.Settings.Default使用依赖注入?

例如为:

public class Foo 
{ 
    private _settings; 
    private bool _myBool; 

    public Foo(Settings settings) 
    { 
     this._settings = settings; 
     this._myBool = this._settings.MyBool; 
    } 
} 


或者您会考虑使用Settings作为一种广泛的全球应用程序吗?

例如为:

public class Foo 
{ 
    private bool _myBool; 

    public Foo() 
    { 
     this._myBool = Properties.Settings.Default.MyBool; 
    } 
} 

回答

2

你可能想要在一个类中封装设置并为它们设置一个接口。这样,你的设置来自哪里可以改变,比如单元测试。如果您还在使用IoC容器,那么通过所有方法注册容器的设置。

我这样做的ConfigurationManagerWebConfigurationManager,这样我可以注入测试设置。 Nathan Gloyn has wrapped the adapters and interface up already in a project,你可以使用,如果你也想这样做。

+0

我喜欢接口的想法,但我不知道如何去实现它。你的意思是有一个接口的属性可以直接映射到Settings中的属性,或者使用ConfigurationManager,就像你链接的代码一样?之前没有使用ConfigurationManager,所以不太确定在这里做什么。另一个微调正确的方向将不胜感激。 :) – Andy

+0

'IConfigurationManager'只是外部设置可能在应用程序中的一个示例,您希望它们由容器处理并注入类中。对于你的'设置'类,我倾向于创建一个与'Settings'的公共成员最匹配的'ISettings'接口;所以如果你在'Settings'上有'ConnectionString'属性,那么就把它作为接口上的一个属性,等等。 –

+0

感谢你澄清,这是有道理的。 – Andy

2

他们应该被传递作为一个依赖。想象一下当你想在你的例子#2中通过单元测试改变这组设置的场景 - 你必须在静态属性getter中有一些复杂的开关逻辑来适应这种情况。

许多IoC容器甚至可以在注入这样的类时提供单例实现以帮助您。

4

我会选择“以上都不是”,并直接注入布尔值:从支持布尔值的检索任何基础设施方面的知识

public class Foo 
{ 
    private readonly bool _myBool; 

    public Foo(bool myBool) 
    { 
     _myBool = myBool; 
    } 
} 

这样可以使FooFoo没有理由根据设置对象引入复杂性,特别是如果它包含其他不相关的值。

+0

+1,但请注意,使用DI容器进行配置会非常困难。尽管如此,仍然可能是最好的想法。 – Domenic

+0

@Domenic:绝对值得注意的是,一些DI容器可能无法像其他容器一样轻松实现。我使用Autofac,它支持lambda表达式进行注册,因此可以轻松注入原始值。 –

+0

@Bryan:我同意,但我上面的代码片段被作为一个过于简单的例子来解决这个问题。然而,你说的是对的,所以谢谢你的回答。 – Andy