单身人士模式的替代品?

Bre*_*ogt 7 singleton design-patterns

我有一段时间以来一直是Web开发人员使用ASP.NET和C#,我想尝试通过使用最佳实践来提高我的技能.

我有一个网站.我想一次性加载设置,并在我需要的地方引用它.所以我做了一些研究,50%的开发人员似乎都在使用单例模式来做这件事.其他50%的开发人员都是蚂蚁单身人士.他们都讨厌单身人士.他们建议依赖注入.

为什么单身人士不好?加载网站设置的最佳做法是什么?它们应该只加载一次并在需要的地方引用吗?我将如何通过依赖注入来实现这一点(我是新手)?是否有人可以为我的方案推荐的样品?我也希望看到一些单元测试代码(对于我的场景).

谢谢布兰登

tva*_*son 6

一般来说,我避免使用单例,因为它们会使单元测试应用程序变得更加困难.单身人士难以嘲笑单位测试,因为他们的性质 - 你总是得到同一个,而不是你可以轻松配置的单元测试.配置数据 - 无论如何强类型配置数据 - 是我做的一个例外.通常,配置数据无论如何都是相对静态的,并且备选方案涉及编写相当数量的代码以避免框架提供的静态类来访问web.config.

有几种不同的使用方法,仍然允许您对应用程序进行单元测试.一种方法(可能两种方式,如果您的单身人士不懒惰地阅读app.cofnig)是在单元测试项目中有一个默认的app.config文件,提供测试所需的默认值.您可以使用反射替换单元测试中所需的任何特定值.通常,我会配置一个私有方法,如果我确实对特定测试进行了更改,则允许在测试设置中删除私有单例实例.

另一种方法是不实际直接使用的单,但对于它的单类实现创建一个接口.您可以使用手动注入接口,如果提供的值为null,则默认为单例实例.这使您可以创建一个模拟实例可以传递到类测试你的测试,但您的真实代码中使用单一实例.本质上,每个需要它的类都维护对单例实例的私有引用并使用它.我喜欢这种方式更好一点,但因为单将被创建,你可能仍然需要默认app.config文件,除非所有值都延迟加载.

public class Foo
{
    private IAppConfiguration Configuration { get; set; }

    public Foo() : this(null) { }

    public Foo( IAppConfiguration config )
    {
        this.Configuration = config ?? AppConfiguration.Instance;
    }

    public void Bar()
    {
         var value = this.Config.SomeMaximum;
         ...
    }
}    
Run Code Online (Sandbox Code Playgroud)