Best place to keep singleton instances - c#

Where is the best spot to store instances of singleton classes?
Say for instance I have a configuration class (which loads global settings for the application), and perhaps a class that accesses a web service, I am not sure where the best spot to instantiate these, and to keep them.
Currently, I have them as instances of the Program class (where Application.Run is called from), and it seems to work fine, but I am unsure if thats the best method!...
static class Program
{
public static string dbConnectString = "Data Source=" +
Path.GetDirectoryName(Assembly.GetExecutingAssembly().GetName().CodeBase) +
#"\xxx.sdf" + ";Persist Security Info=False";
public static Settings settings = null;
[MTAThread]
static void Main()
{
settings = Settings.Instance;
Application.Run(new MainMenu());
}
}
And throughout the application, I am calling it like this:
txtWebServiceUrl.Text = Program.settings.getSetting("web_service_url");
Is there anything wrong with this, or what is the best method?
Thanks!

I personally would make 'em nice and easy to get to - putting 'em in a 'Settings' or 'Global' class. Oh, and if possible I'd have properties [or enum] to access the settings rather than a string key so intellisense can bash you over the head when you make a typo.
public static class Settings
{
static Dictionary<string,string> data = new Dictionary<string,string>();
public static string WebServiceUrl {get {return data["web_service_url"];}}
}
Used like so:
txtWebServiceUrl.Text = Settings.WebServiceUrl;
Though obviously this is optional.
Hope that helps.

You are missing the point of the Singleton pattern. You don't store a reference to Singletons as there is intended to only be a single reference, controlled by the Singleton.
The pattern works in that anywhere you need to use the Singleton, you reference it through it's single Instance, in your case: Settings.Instance.
Singletons themselves are a bit of a smell in that by nature they break Inversion of Control, making code more difficult to test. In legacy applications where I've run into Singletons and Static Classes I tend to modify them to extend an interface. (I.e. ISettings) which exposes the desired behaviour, then utilize something like a lazy-load dependency into the classes that want to access it:
private ISettings _settings;
public ISettings Settings
{
get { return _settings ?? Settings.Instance;}
set { _settings = value; }
}
This allows your tests to substitute the settings with a stub/mock. It defaults to the Singleton. It's an effective, lightweight re-factor that enables some testability in code that relies on Singletons and Statics.

Related

Dependency injection pattern how to initialize variables of static class at beginning

I've been using dependency injection for about 6 months now and sometimes there is a situation I don't know how to handle in an elegant way.
Say I want a class for storing all my app settings in. This class is only initialized at beginning.
Please let me know how idea 1 can be executed (as I think this is the classic way) and if idea 2 is a valid pattern or if there is a better alternative.
Idea 1:
make this class static as its variables are only initialized and after that everything stays read-only. The problem with this is that I do not know where to initialize variables of this class. To initialize one of the variables a password needs to be decrypted which requires the use of IEncryption interface.
I would like to initialize these static variables before the main program actually start (so preferably in Startup.cs). I can't do that because I can't get the implementation of IEncryption in the DI container class, or at least I don't know an elegant way to get it. How should this be done with a static class? should I make another "middleware" between Startup and actual program logic where I can initialize static variables?
If I'm not mistaken simple data only classes that are application wide are ok to be static object even when using DI pattern
Idea 2:
Now I don't know if this has a name or if it's ever used. It's just something I came up with and it seems like a good solution for me but there might be an alternative I don't know of that makes it useless.
What if I instead of making this class static I make it as a normal class and initialize all static variables inside class constructor.
So something like this:
public ClientData(IConfiguration configuration, IEncryption encryption)
{
var section = configuration.GetSection(nameof(ClientData));
EdgeUrl = section.GetValue<string>(nameof(EdgeUrl));
EdgeAuthUrl = section.GetValue<string>(nameof(EdgeAuthUrl));
Username = section.GetValue<string>(nameof(Username));
Password = encryption.Decrypt(section.GetValue<string>(nameof(Password)));
OrganizationKey = section.GetValue<string>(nameof(OrganizationKey));
}
public string EdgeUrl { get; }
public string EdgeAuthUrl { get; }
public string Username { get; }
public string Password { get; }
public string OrganizationKey { get; }
I then inject IEncryption through the constructor.
I would definitely recommend the second approach, except that you should keep the properties as regular properties, and no static fields or properties.
You should be able to register this in the DI container as a 'singleton'. This ensures only one instance is created. So it will be kind of static in the sense that there 'is only one', but only in the context of the DI container rather than for the whole process. This allows more flexibility, for example if you want to different parts of the application to use different configurations.
This will require the class to be injected into each place it is used. Luckily the DI container should make that trivial.

Using constants or global variables in 3 tier console application

I have a 3 tier application setup like so with a console presentation layer. In my business logic I have a class where I declare a number of different variables that are fixed i.e. the values won't change. The values of these variables are taken from app settings.
Now the problem I'm finding is that my class calls off to different methods where these variables are being passed around via the method signatures. Is this good practice? If not, would it not be better using constants instead? If so, where should the constants live so I can access them where ever I need them rather than passing variables around?
EDIT
Adding some code for you guys. So they're global variables I am referring to here.
OK so in my console app (presentation), I currently have something like this:
public class Program
{
public static void Main(string[] args)
{
MainClass myClass = new MainClass(appSetting1, appSetting2, appSetting3);
}
}
Then in MainClass I have:
public class MainClass
{
private string _appSetting1 = string.Empty;
private string _appSetting2 = string.Empty;
private string _appSetting3 = string.Empty;
public MainClass(string appSetting1, string appSetting2, string appSetting3)
{
_appSetting1 = appSetting1;
_appSetting2 = appSetting2;
_appSetting3 = appSetting3;
}
public void MyMethod()
{
Method2(_appSetting1, _appSetting2);
Method3(_appSetting2, _appSetting3);
Method4(_appSetting1, _appSetting3);
}
}
I hope you can see what I mean. I'm finding myself passing around global variables across multiple methods. I just thought there would be an easier way of doing this? Such as creating a constants class or something on the lines of that? I'm not 100% sure of the best approach to go for.
In my MainClass I could just declare my global variables like this:
private string _appSetting1 = ConfigurationManager.AppSettings["appsetting1"];
private string _appSetting2 = ConfigurationManager.AppSettings["appsetting2"];
private string _appSetting3 = ConfigurationManager.AppSettings["appsetting3"];
But do I really want to be doing that in my business logic?
Another possibility is to create a Settings class that loads them and exposes them as public readonly. This has worked well for me in the past:
public class Settings
{
public static readonly string AppSetting1;
public static readonly string AppSetting2;
public static readonly string AppSetting3;
static Settings()
{
AppSetting1 = ConfigurationManager.AppSettings["appsetting1"];
AppSetting2 = ConfigurationManager.AppSettings["appsetting2"];
AppSetting3 = ConfigurationManager.AppSettings["appsetting3"];
}
}
The static constructor is called automatically before the first access to any of the variables, so you don't have to call it explicitly. Your program can access the variables as Settings.AppSetting1, etc.
I am of the config-free mindset.
If these things presumably don't change, then have an assembly that projects can reference that return the values.
I shy away from configuration files. I realise they are needed in deployment circumstances, but given that your requirement, I'd recommend a common class library that everything else can use and reference.
If you do have to change something supposedly constant, you change it in one place.
if they are in the app.config and shouldn't change you should always reference them from there rather than passing them as parameters. This way your intention that they are static values is clear in the code.
EDIT
Jims answer makes sense in that case. Its really just a short hand so instead of writing ConfigurationManager.AppSettings["appsetting1"]; you use Settings.AppSetting1. either way you would be repeating yourself if you declare them at the top every class into class level variables. I like Jim's answer better than mine though as you can extend it. I keep all config in the db and then use a singleton which has a proc call in the private instance constructor to load config. Jims answer could implement this later without you needing to change your calling code. Generally config files are a pain.

What are the differences between these options for a simple interface to a field?

I was just staring at the following code and wondered if there was really a need to fill 12 lines of source.
private static IUnityContainer _container;
public static IUnityContainer Container
{
get
{
return _container;
}
set
{
_container = value;
}
}
My thought is, why not just one?
public static IUnityContainer Container;
I think the answer is something like "you can't break encapsulation".. Is this more of a knee jerk reaction to conditioning, or are there some other reasons, subtle or otherwise?
Well, until you don't want to use reflection in some strange ways, like GetType().GetProperty("Container" ...) there are no drawbacks.
It is however considered unclean to expose a field, a property is usually cleaner from a purist point of view.
FxCop will warn you that it is a not nice thing, but there are not drawbacks.
If you want to be short but clean in the same time, you can just use automatic properties:
public static IUnityContainer Container { get; set; }
Automatic properties however works only since compiler version 3.0.
A possible drawback that can happen is if you or someone pass that field byref in some function, for example, Interlocked.Exchange(ref MyClass.MyStaticField, null);
It will not work anymore if you change it with a property in the future, so you should be careful in not passing that field by reference. If you just use a property from the beginning you cannot have this problem.
This problem cannot happen with static readonly fields, they cannot be passed by reference. Using static readonly fields is quite common.
A situation where fields should absolutely not be used instead of properties is when you have a class that inherits MarshalByRefObject, used for remoting (RPC, remote procedure call).
Here I post an example, and as I said, is not your case since the problem is with instance fields and not with static fields.
public class MyClass :
MarshalByRefObject
{
public int MyValue;
}
class Program
{
static void Main(string[] args)
{
var obj = new MyClass();
// This will give you warning CS1690: Accessing a member on 'MyValue' may cause a runtime exception because it is a field of a marshal-by-reference class
Console.WriteLine(obj.MyValue.ToString());
}
}
Remote procedure call works only with methods and properties, for this reason the compiler gives you a warning, since a MarshalByRefObject can be called inside another AppDomain or by another process or another computer via TCP/IP for example.
Personally, I think of it this way. Let's say that at some later time, I want to establish an inavariant that "Container" is never null. If it's defined as a public field, the way to enforce this would be to seek out each and every client that uses it and put code in preventing it from being set to null. If I have it as a property, the same can be accomplished with something like:
private static IUnityContainer _container = new ContainerImpl();
public static IUnityContainer Container
{
get
{
return _container;
}
set
{
_container = value ?? _container;
}
}
Or, you could throw an exception on null value to be more expressive. The specifics aren't important, but the encapsulation angle is.
So, I think that's not simply a knee-jerk reaction, but a pragmatic and reasonable one, especially in the face of the static keyword. Without encapsulation, that's literally just a global variable. At least encapsulating the global state allows the provider some semblance of control over it, rather than leaking control all over the entire application and trusting/forcing clients to be consistent.
One might look at it as a matter of "Don't Repeat Yourself". Any common logic when it comes to a field will necessarily be duplicated all over the place.

Dependency Injection and AppSettings

Let's say I am defining a browser implementation class for my application:
class InternetExplorerBrowser : IBrowser {
private readonly string executablePath = #"C:\Program Files\...\...\ie.exe";
...code that uses executablePath
}
This might at first glance to look like a good idea, as the executablePath data is near the code that will use it.
The problem comes when I try to run this same application on my other computer, that has a foreign-language OS: executablePath will have a different value.
I could solve this through an AppSettings singleton class (or one of its equivalents) but then no-one knows my class is actually dependent on this AppSettings class (which goes against DI ideias). It might pose a difficulty to Unit-Testing, too.
I could solve both problems by having executablePath being passed in through the constructor:
class InternetExplorerBrowser : IBrowser {
private readonly string executablePath;
public InternetExplorerBrowser(string executablePath) {
this.executablePath = executablePath;
}
}
but this will raise problems in my Composition Root (the startup method that will do all the needed classes wiring) as then that method has to know both how to wire things up and has to know all these little settings data:
class CompositionRoot {
public void Run() {
ClassA classA = new ClassA();
string ieSetting1 = "C:\asdapo\poka\poskdaposka.exe";
string ieSetting2 = "IE_SETTING_ABC";
string ieSetting3 = "lol.bmp";
ClassB classB = new ClassB(ieSetting1);
ClassC classC = new ClassC(B, ieSetting2, ieSetting3);
...
}
}
which will turn easily a big mess.
I could turn this problem around by instead passing an interface of the form
interface IAppSettings {
object GetData(string name);
}
to all the classes that need some sort of settings. Then I could either implement this either as a regular class with all the settings embedded in it or a class that reads data off a XML file, something along the lines. If doing this, should I have a general AppSettings class instance for the whole system, or have an AppSettings class associated to each class that might need one? That certainly seems like a bit of an overkill. Also, have all the application setings in the same place makes it easy to look and see what might be all the changes I need to do when tryign to move the program to different platforms.
What might be the best way to approach this common situation?
Edit:
And what about using an IAppSettings with all its settings hardcoded in it?
interface IAppSettings {
string IE_ExecutablePath { get; }
int IE_Version { get; }
...
}
This would allow for compile-time type-safety. If I saw the interface/concrete classes grow too much I could create other smaller interfaces of the form IMyClassXAppSettings. Would it be a burden too heavy to bear in med/big sized projects?
I've also reading about AOP and its advantages dealing with cross-cutting-concerns (I guess this is one). Couldn't it also offer solutions to this problem? Maybe tagging variables like this:
class InternetExplorerBrowser : IBrowser {
[AppSetting] string executablePath;
[AppSetting] int ieVersion;
...code that uses executablePath
}
Then, when compiling the project we'd also have compile time safety (having the compiler check that we actually implemented code that would weave in data. This would, of course, tie our API to this particular Aspect.
The individual classes should be as free from infrastructure as possible - constructs like IAppSettings, IMyClassXAppSettings, and [AppSetting] bleed composition details to classes which, at their simplest, really only depend on raw values such as executablePath. The art of Dependency Injection is in the factoring of concerns.
I have implemented this exact pattern using Autofac, which has modules similar to Ninject and should result in similar code (I realize the question doesn't mention Ninject, but the OP does in a comment).
Modules organize applications by subsystem. A module exposes a subsystem's configurable elements:
public class BrowserModule : Module
{
private readonly string _executablePath;
public BrowserModule(string executablePath)
{
_executablePath = executablePath;
}
public override void Load(ContainerBuilder builder)
{
builder
.Register(c => new InternetExplorerBrowser(_executablePath))
.As<IBrowser>()
.InstancePerDependency();
}
}
This leaves the composition root with the same problem: it must supply the value of executablePath. To avoid the configuration soup, we can write a self-contained module which reads configuration settings and passes them to BrowserModule:
public class ConfiguredBrowserModule : Module
{
public override void Load(ContainerBuilder builder)
{
var executablePath = ConfigurationManager.AppSettings["ExecutablePath"];
builder.RegisterModule(new BrowserModule(executablePath));
}
}
You could consider using a custom configuration section instead of AppSettings; the changes would be localized to the module:
public class BrowserSection : ConfigurationSection
{
[ConfigurationProperty("executablePath")]
public string ExecutablePath
{
get { return (string) this["executablePath"]; }
set { this["executablePath"] = value; }
}
}
public class ConfiguredBrowserModule : Module
{
public override void Load(ContainerBuilder builder)
{
var section = (BrowserSection) ConfigurationManager.GetSection("myApp.browser");
if(section == null)
{
section = new BrowserSection();
}
builder.RegisterModule(new BrowserModule(section.ExecutablePath));
}
}
This is a nice pattern because each subsystem has an independent configuration which gets read in a single place. The only benefit here is a more obvious intent. For non-string values or complex schemas, though, we can let System.Configuration do the heavy lifting.
I'd go with the last option - pass in an object that complies with the IAppSettings interface. In fact, I recently performed that refactor at work in order to sort out some unit tests and it worked nicely. However, there were few classes dependent on the settings in that project.
I'd go with creating a single instance of the settings class, and pass that in to anything that's dependant upon it. I can't see any fundamental problem with that.
However, I think you've already thought about this and seen how it can be a pain if you have lots of classes dependent on the settings.
If this is a problem for you, you can work around it by using a dependency injection framework such as ninject (sorry if you're already aware of projects like ninject - this might sound a bit patronizing - if you're unfamiliar, the why use ninject sections on github are a good place to learn).
Using ninject, for your main project you can declare that you want any class with a dependency on IAppSettings to use a singleton instance of your AppSettings based class without having to explicitly pass it in to constructors everywhere.
You can then setup your system differently for your unit tests by stating that you want to use an instance of MockAppSettings wherever IAppSettings is used, or by simply explicitly passing in your mock objects directly.
I hope I've got the gist of your question right and that I've helped - you already sound like you know what you're doing :)

Taking baby-steps in applying a better design

In wanting to get some hands-on experience of good OO design I've decided to try to apply separation of concerns on a legacy app.
I decided that I wasn't comfortable with these calls being scattered all over the code base.
ConfigurationManager.AppSettings["key"]
While I've already tackled this before by writing a helper class to encapsulate those calls into static methods I thought it could be an opportunity to go a bit further.
I realise that ultimately I should be aiming to use dependency injection and always be 'coding to interfaces'. But I don't want to take what seems like too big a step. In the meantime I'd like to take smaller steps towards that ultimate goal.
Can anyone enumerate the steps they would recommend?
Here are some that come to mind:
Have client code depend on an interface not a concrete implementation
Manually inject dependencies into an
interface via constructor or property?
Before going to the effort of
choosing and applying an IoC
container how do I keep the code
running?
In order to fulfil a dependency the default
constructor of any class that needs a
configuration value could use a Factory
(with a static CreateObject() method)?
Surely I'll still have a concrete dependency on the Factory?...
I've dipped into Michael Feathers' book so I know that I need to introduce seams but I'm struggling to know when I've introduced enough or too many!
Update
Imagine that Client calls methods on WidgetLoader passing it the required dependencies (such as an IConfigReader)
WidgetLoader reads config to find out what Widgets to load and asks WidgetFactory to create each in turn
WidgetFactory reads config to know what state to put the Widgets into by default
WidgetFactory delegates to WidgetRepository to do the data access, which reads config to decide what diagnostics it should log
In each case above should the IConfigReader be passed like a hot potato between each member in the call chain?
Is a Factory the answer?
To clarify following some comments:
My primary aim is to gradually migrate some app settings out of the config file and into some other form of persistence. While I realise that with an injected dependency I can Extract and Override to get some unit testing goodness, my primary concern is not testing so much as to encapsulate enough to begin being ignorant of where the settings actually get persisted.
When refactoring a legacy code-base you want to iteratively make small changes over time. Here is one approach:
Create a new static class (i.e. MyConfigManager) with a method to get the app setting (i.e. GetAppSettingString( string key )
Do a global search and replace of "ConfigurationManager.AppSettings["key"] and replace instances with "MyConfigManager.GetAppSettingsString("key")"
Test and check-in
Now your dependency on the ConfigurationManager is in one place. You can store your settings in a database or wherever, without having to change tons of code. Down side is that you still have a static dependency.
Next step would be to change MyConfigManager into a regular instance class and inject it into classes where it is used. Best approach here is to do it incrementally.
Create an instance class (and an interface) alongside the static class.
Now that you have both, you can refactor the using classes slowly until they are all using the instance class. Inject the instance into the constructor (using the interface). Don't try for the big bang check-in if there are lots of usages. Just do it slowly and carefully over time.
Then just delete the static class.
Usually its very difficult to clean a legacy application is small steps, because they are not designed to be changed in this way. If the code is completely intermingled and you have no SoC it is difficult to change on thing without being forced to change everything else... Also it is often very hard to unit test anything.
But in general you have to:
1) Find the simplest (smallest) class not refactored yet
2) Write unit tests for this class so that you have confidence that your refactoring didn't break anything
3) Do the smallest possible change (this depends on the project and your common sense)
4) Make sure all the tests pass
5) Commit and goto 1
I would like to recommend "Refactoring" by Martin Fowler to give you more ideas: http://www.amazon.com/exec/obidos/ASIN/0201485672
For your example, the first thing I'd do is to create an interface exposing the functionality you need to read config e.g.
public interface IConfigReader
{
string GetAppSetting(string key);
...
}
and then create an implementation which delegates to the static ConfigurationManager class:
public class StaticConfigReader : IConfigReader
{
public string Get(string key)
{
return ConfigurationManager.AppSetting[key];
}
}
Then for a particular class with a dependency on the configuration you can create a seam which initially just returns an instance of the static config reader:
public class ClassRequiringConfig
{
public void MethodUsingConfig()
{
string setting = this.GetConfigReader().GetAppSetting("key");
}
protected virtual IConfigReader GetConfigReader()
{
return new StaticConfigReader();
}
}
And replace all references to ConfigManager with usages of your interface. Then for testing purposes you can subclass this class and override the GetConfigReader method to inject fakes so you don't need any actual config file:
public class TestClassRequiringConfig : ClassRequiringConfig
{
public IConfigReader ConfigReader { get; set; }
protected override IConfigReader GetConfigReader()
{
return this.ConfigReader;
}
}
[Test]
public void TestMethodUsingConfig()
{
ClassRequiringConfig sut = new TestClassRequiringConfig { ConfigReader = fakeConfigReader };
sut.MethodUsingConfig();
//Assertions
}
Then eventually you will be able to replace this with property/constructor injection when you add an IoC container.
EDIT:
If you're not happy with injecting instances into individual classes like this (which would be quite tedious if many classes depend on configuration) then you could create a static configuration class, and then allow temporary changes to the config reader for testing:
public static class Configuration
{
private static Func<IConfigReader> _configReaderFunc = () => new StaticConfigReader;
public static Func<IConfigReader> GetConfiguration
{
get { return _configReaderFunc; }
}
public static IDisposable CreateConfigScope(IConfigReader reader)
{
return new ConfigReaderScope(() => reader);
}
private class ConfigReaderScope : IDisposable
{
private readonly Func<IConfigReader> _oldReaderFunc;
public ConfigReaderScope(Func<IConfigReader> newReaderFunc)
{
this._oldReaderFunc = _configReaderFunc;
_configReaderFunc = newReaderFunc;
}
public void Dispose()
{
_configReaderFunc = this._oldReaderFunc;
}
}
}
Then your classes just access the config through the static class:
public void MethodUsingConfig()
{
string value = Configuration.GetConfigReader().GetAppSetting("key");
}
and your tests can use a fake through a temporary scope:
[Test]
public void TestMethodUsingConfig()
{
using(var scope = Configuration.CreateConfigScope(fakeReader))
{
new ClassUsingConfig().MethodUsingConfig();
//Assertions
}
}

Categories