Dependency injection / service locator

Features:

  • Register any type or object as an interface or base type
  • Create objects at runtime using dependency injection

ServiceRepository / ServiceLocator

You can have more than one ServiceRepository object to resolve dependencies but this is not a common use case. One static repository is available as ServiceRepository.Default. Alternatively, the static class ServiceLocator maps to ServiceRepository.Default.

You can register a class or object that implements a base class or interface in a service repository:

public interface IService
{
   void Action();
}

public class ServiceImplementation : IService
{
   public void Action() {}
}
ServiceLocator.Register(new ServiceImplementation());
// or
ServiceLocator.Register<ServiceImplementation>();
var service = ServiceLocator.Get<IService>();

If a service implements more than one interface, it can be registered as one specific interface:

public interface IService1
{
   void Action();
}

public interface IService2
{
   void Go();
}

public class ServiceA: IService1, IService2
{
   public void Action() {}
   public void Go {}
}

public class ServiceB : IService1, IService2
{
   public void Action() {}
   public void Go {}
}

Register ServiceA and it will resolve when retrieving IService1 and IService2:

ServiceLocator.Register(new ServiceA());
//
var svc1 = ServiceLocator.Get<IService1>(); // returns ServiceA instance
var svc2 = ServiceLocator.Get<IService2>(); // returns ServiceA instance

Register ServiceA as IService1 and register ServiceB as IService2:

ServiceLocator.Register(new ServiceA()).As<IService1>();
ServiceLocator.Register(new ServiceB()).As<IService2>();

//

var svc1 = ServiceLocator.Get<IService1>(); 
var svc2 = ServiceLocator.Get<IService2>(); 

// svc1 == ServiceA instance
// svc2 == ServiceB instance

When a type is registered using only the type name, a parameterless public constructor should exist.