How Dependency Injection/IOC Containers Determine Implementation

dependency-injectioninversion-of-controlioc-containers

When you use an IoC container, like so:

var svc = IoC.Resolve<IShippingService>();

How does the IoC Container choose which implementation of IShippingService to instantiate?

Further, if I am calling the above to replace the equivalent code:

var svc = new ShippingService(new ProductLocator(), 
   new PricingService(), new InventoryService(), 
   new TrackingRepository(new ConfigProvider()), 
   new Logger(new EmailLogger(new ConfigProvider())));

I assume that ProductLocator, PricingService, etc. are called out in the constructor parameters as Interfaces, not concrete classes. How does the IoC container know which implementations of IProductLocator, IPricingService, etc. to instantiate?

Is the IoC Container smart enough to use the same ConfigProvider for both dependencies (if that is the requirement)?

Best Answer

Because you pass configure to it which tells it how to do it. Typically this happens during application startup.

In the simplest case you could have a lot of lines like:

iocConfig.Bind<IShippingService>().To<ShippingService>();

There are different ways to define such a configuration, such as conventions (e.g. a concrete class matching the name of the interface apart from the I prefix), attributes or config files, each with their own advantages and disadvantages.

When testing you could create the stubs manually, or use a different configuration.


Most containers also support a way for the target site to influence the dependency resolution, for example by adding an attribute. Personally I haven't needed that so far.


Reuse of instances is determined by scope. Typically you have one scope where nothing gets reused (transient), per-request scope, per-thread scope, singleton scope, etc. You typically specify the scope as part of the configuration.

Related Topic