An Example

May 7, 2009 at 10:27 PM
Edited May 7, 2009 at 10:28 PM
Is there a link or an example somewhere showing how to use the Common Service Locator with two different DI frameworks?

TIA
Yaz
Jan 8, 2010 at 1:17 PM

While possible, this is not a typical thing to do. Implementing such a thing isn't actually that hard, because you can create a router that routes requests to one of the underlying DI framework. The hard part probably is determining to which framework each request must be routed.

But since you’re asking for an example, here’s one. Below is an example of how to do this. For the sake of argument, I use the same DI framework (Simple Service Locator in this case) twice, which is of course a bit silly, but you'll get the idea.

The example shows the configuration of the two containers and the creation of the router that delegates calls to one of given containers. The router is configured with a delegate that contains the actual logic to get the correct container for a given type. In this case requests for all types in System.* namespaces will be delegated to the ‘systemContainer’ and all other requests will be delegated to the ‘applicationContainer’. Of course this logic is a bit naïve and could be much more complicated determined by your need.

 

static void Main(string[] args)
{
    // Create and configure the first container
    var systemContainer = new SimpleServiceLocator();

    systemContainer.Register<System.Data.IDbConnection>(() => 
        new SqlConnection(ConfigurationManager.ConnectionStrings[0]
            .ConnectionString));

    // Create and configure the second container
    var applicationContainer = new SimpleServiceLocator();

    applicationContainer.RegisterSingle<MyApp.IWeapon>(new Katana());

    // Create the router
    var router = new ServiceLocatorRouter()
    {
        ServiceLocatorResolver = serviceType =>
        {
            if (serviceType.Namespace.StartsWith("System"))
                return systemContainer;
            else
                return applicationContainer;
        }
    };

    // Register the router as service locator
    ServiceLocator.SetLocatorProvider(() => router);

    // Rest of the application
}

Below is the implementation of the ServiceLocatorRouter:

public class ServiceLocatorRouter : ServiceLocatorImplBase
{
    public Func<Type, IServiceLocator> ServiceLocatorResolver { get; set; }

    protected override IEnumerable<object> DoGetAllInstances(Type serviceType)
    {
        return this.Find(serviceType).GetAllInstances(serviceType);
    }

    protected override object DoGetInstance(Type serviceType, string key)
    {
        return this.Find(serviceType).GetInstance(serviceType, key);
    }

    private IServiceLocator Find(Type serviceType)
    {
        return this.ServiceLocatorResolver(serviceType);
    }
}
I hope this helps.