To start building an IOC container with Microsoft's DI nuget package you start with creating an IServiceCollection
. You can use the already provided Collection: ServiceCollection
:
var services = new ServiceCollection();
This IServiceCollection
is nothing more than an implementation of: IList<ServiceDescriptor>, ICollection<ServiceDescriptor>, IEnumerable<ServiceDescriptor>, IEnumerable
All the following methods are only extension methods to add ServiceDescriptor
instances to the list:
services.AddTransient<Class>(); //add registration that is always recreated
services.AddSingleton<Class>(); // add registration that is only created once and then re-used
services.AddTransient<Abstract, Implementation>(); //specify implementation for interface
services.AddTransient<Interface>(serviceProvider=> new Class(serviceProvider.GetService<IDependency>())); //specify your own resolve function/ factory method.
services.AddMvc(); //extension method by the MVC nuget package, to add a whole bunch of registrations.
// etc..
//when not using an extension method:
services.Add(new ServiceDescriptor(typeof(Interface), typeof(Class)));
The serviceprovider is the one 'Compiling' all the registrations so that they can be used quickly, this can be done with services.BuildServiceProvider()
which is basically an extension mehtod for:
var provider = new ServiceProvider( services, false); //false is if it should validate scopes
Behind the scenes every ServiceDescriptor
in the IServiceCollection
gets compiled to a factory method Func<ServiceProvider, object>
where object is the return type and is: the created instance of the Implementation type, the Singleton or your own defined factory method.
These registrations get added to the ServiceTable
which is basically a ConcurrentDictionary
with the key being the ServiceType
and the value the Factory method defined above.
Now we have a ConcurrentDictionary<Type, Func<ServiceProvider, object>>
which we can use concurrently to ask to create Services for us. To show a basic example of how this could have looked.
var serviceProvider = new ConcurrentDictionary<Type, Func<ServiceProvider, object>>();
var factoryMethod = serviceProvider[typeof(MyService)];
var myServiceInstance = factoryMethod(serviceProvider)
This is not how it works!
This ConcurrentDictionary
is a property of the ServiceTable
which is a property of the ServiceProvider