Alternatives for the singleton pattern?

后端 未结 4 999
既然无缘
既然无缘 2021-01-05 10:35

I have been a web developer for some time now using ASP.NET and C#, I want to try and increase my skills by using best practices.

I have a website. I want to load t

相关标签:
4条回答
  • 2021-01-05 10:39

    There's a good discussion of singleton patterns, and coding examples here... http://en.wikipedia.org/wiki/Singleton_pattern See also here... http://en.wikipedia.org/wiki/Dependency_injection

    For some reason, singletons seem to divide programmers into strong pro- and anti- camps. Whatever the merits of the approach, if your colleagues are against it, it's probably best not to use one. If you're on your own, try it and see.

    0 讨论(0)
  • 2021-01-05 10:45

    One way to approach this problem, is to flog it off as a DAL problem.

    Whatever class / web page, etc. needs to use config settings should declare a dependency on an IConfigSettingsService (factory/repository/whatever-you-like-to-call-them).

    private IConfigSettingsService _configSettingsService;
    
    public WebPage(IConfigSettingsService configSettingsService)
    {
        _configSettingsService = configSettingsService;
    }
    

    So your class would get settings like this:

    ConfigSettings _configSettings = _configSettingsService.GetTheOnlySettings();
    

    the ConfigSettingsService implementation would have a dependency which is Dal class. How would that Dal populate the ConfigSettings object? Who cares.

    • Maybe it would populate a ConfigSettings from a database or .config xml file, every time.

    • Maybe it do that the first time but then populate a static _configSettings for subsequent calls.

    • Maybe it would get the settings from Redis. If something indicates the settings have changed then the dal, or something external, can update Redis. (This approach will be useful if you have more than one app using the settings.

    Whatever it does, your only dependency is a non-singleton service interface. That is very easy to mock. In your tests you can have it return a ConfigSettings with whatever you want in it).

    In reality it would more likely be MyPageBase which has the IConfigSettingsService dependency, but it could just as easily be a web service, windows service, MVC somewhatsit, or all of the above.

    0 讨论(0)
  • 2021-01-05 10:48

    Generally, I avoid singletons because they make it harder to unit test your application. Singletons are hard to mock up for unit tests precisely because of their nature -- you always get the same one, not one you can configure easily for a unit test. Configuration data -- strongly-typed configuration data, anyway -- is one exception I make, though. Typically configuration data is relatively static anyway and the alternative involves writing a fair amount of code to avoid the static classes the framework provides to access the web.config anyway.

    There are a couple of different ways to use it that will still allow you to unit test you application. One way (maybe both ways, if your singleton doesn't lazily read the app.cofnig) is to have a default app.config file in your unit test project providing the defaults required for your tests. You can use reflection to replace any specific values as needed in your unit tests. Typically, I'd configure a private method that allows the private singleton instance to be deleted in test set up if I do make changes for particular tests.

    Another way is to not actually use the singleton directly, but create an interface for it that the singleton class implements. You can use hand injection of the interface, defaulting to the singleton instance if the supplied value is null. This allows you to create a mock instance that you can pass to the class under test for your tests, but in your real code use the singleton instance. Essentially, every class that needs it maintains a private reference to the singleton instance and uses it. I like this way a little better, but since the singleton will be created you may still need the default app.config file, unless all of the values are lazily loaded.

    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;
             ...
        }
    }    
    
    0 讨论(0)
  • 2021-01-05 10:57

    Design Patterns can be amazing things. Unfortunately, the singleton seems to stick out like a sore thumb and in many cases can be considered an anti-pattern (it promotes bad practices). Bizarely, the majority of developers will only know one design pattern, and that is the singleton.

    Ideally your settings should be a member variable in a high level location, for example the application object which owns the webpages you are spawning. The pages can then ask the app for the settings, or the application can pass the settings as pages are constructed.

    0 讨论(0)
自定义标题
段落格式
字体
字号
代码语言
提交回复
热议问题