Q:

Generic Getter for a collection of Service classes?

I'm building an application in Unity-C#, where everything is referenced under an App class in an MVC pattern. An App instance will make use of several Service classes for doing different data-related things, and all of these Service classes derive from Service.ServiceAbstract, which only contains a basic constructor as well as a Getter for a reference to the relevant App instance.
Ideally what I want is for the App instance to itself create and store all of the services in some kind of container, as well as have a Getter method to return a reference to a requested service. Currently, it is done like this;
private Dictionary<Service.ServiceNames, Service.ServiceAbstract> _services = null;

public Service.ServiceAbstract GetService(Service.ServiceNames serviceName)
{
    return _services[serviceName] as Service.ServiceAbstract;
}

The problems I'm having with this implementation are twofold;

Service.ServiceNames is an enum, which increases the maintainability requirement every time a new Service class has to be created.
The way to retrieve a method inside one of these services looks like this;
((Service.AudioService)[Service.ServiceNames.AUDIO]).DoSomething();
This becomes unwieldy when I need to pass data from one service to another;
((Service.ErrorService)[Service.ServiceNames.ERROR]).CreateErrorPopup(((Service.LocaleService)[Service.ServiceNames.LOCALE]).GetString("GENERIC_ERROR"));

What I would like is some kind of generic method that can take in the Type of Service to get, and then return a reference to that service, without any need to cast or use enums by the callers. I know of the existence of <T> Generics, but I've never created something with them and I'm unsure of a good way to store my services and then return them directly.

A:

You can use Type instead of enum. In this case you can utilize generic function and type casting.
private Dictionary<Type, Service.ServiceAbstract> _services = null;

public T GetService<T>()
{
    return _services[typeof(T)] as T;
}

// And then use

GetService<Service.ErrorService>().CreateErrorPopup(GetService<Service.LocaleService>().GetString("GENERIC_ERROR"));

If you want to initialize your services with default constructor and if you will not have concurrent threads calling GetService<T>() you can use this code as well, that will assist you to not initialize _services manually.
public T GetService<T>() where T : new()
{
    if(!_services.ContainsKey(typeof(T)))
    {
        _services[typeof(T)] = new T();
    }
    return _services[typeof(T)] as T;
}

