Maxim V. Pavlov
Maxim V. Pavlov

Reputation: 10509

Architecturally replace singleton main object with IoC Container

My question is about software architecture in general.

Let's consider an example:

We have a Windows Service application.

Program.cs creates and starts an instance of MainService class.

MainService inherits from ServiceBase therefore implements OnStart(string[] args) method.

Usually, when I design my application, I would do something like this in OnStart method:

MainSingletonObject.Initialize();

Initialize would read the config data from app.config and create an instances of required classes, open WCF hosts (if any), etc.

Is this a good practice to start a service application? What would be your personal architectural advice to improve the design? Where to fit an IoC container and why would I need it if I am doing a dependency injection by hand fine.

Upvotes: 0

Views: 669

Answers (2)

Felice Pollano
Felice Pollano

Reputation: 33252

I would use the IoC in the service bootstrap phase here:

ServiceBase[] ServicesToRun;
            ServicesToRun = new ServiceBase[] 
                { 
                    new ServiceClass() 
                };
            ServiceBase.Run(ServicesToRun);

Instead of having new ServiceClass, I would resolve the service class via IoC. So you avoid having an IoC dependency in the service implementation. If you need to construct via injection a brand new object from inside your implementation consider exposing a service ITypeFactory registered in the IoC that insulates your code from the particular container you will use. In general, you can measure a good design in IoC if you insulate the container too.

Upvotes: 1

Aliostad
Aliostad

Reputation: 81660

Singleton must not depend on others to initialise it. It is initialised as soon as it is used.

This is how I would do it:

public class MySingleton
{
    private static readonly MySingleton _instance = new MySingleton();

    private MySingleton()
    {
        // ... read config
    }

    public static MySingleton Instance
    {
        get { return _instance; }
    }
}

Here static readonly makes sure this is lazy load.

Upvotes: 0

Related Questions