As per my understanding, Dependency Injection container will register all classes during startup of application. How do I access the container when I go from one class library to another. Should container be static/global or container be passed to the called class in constructor.
As per my understanding, Dependency Injection container will register all classes during startup of application.
Correct
How do I access the container when I go from one class library to another.
You don't. Only the start-up path of the application should have access to the Container
. Class libraries should not have a dependency on the DI Container, nor an abstraction that allows it to resolve any component. Spoken in DI terminology: to prevent using the DI Container as a Service Locator, you should refrain from using it outside the Composition Root.
As an example, consider the following classes in your application:
public class OrderController { } // Presentation Layer
public class PlaceOrderHandler { } // Business Layer
public class SqlOrderRepository { } // Data Access Layer
In this example OrderController
requires a PlaceOrderHandler
to function, which in turn requires an OrderRepository
.
Best practice is to apply Constructor Injection, which means that each class defines its required dependencies through its (sole) constructor. For instance:
public class OrderController
{
public OrderController(IHandle<PlaceOrder> handler) { ... }
public void PlaceOrder(PlaceOrderViewModel vm) { ... }
}
public class PlaceOrderHandler : IHandle<PlaceOrder>
{
public PlaceOrderHandler(IOrderRepository repository) { ... }
public void Handle(PlaceOrder command) { ... }
}
public class SqlOrderRepository : IOrderRepository
{
public SqlOrderRepository(string connectionString) { ... }
public Order GetById(Guid id) { ... }
public void Save(Order order) { ... }
}
This allows your Composition Root to compose the following object graph:
new OrderController(
new PlaceOrderHandler(
new SqlOrderRepository(
connectionString)));
This way, none of the classes require a dependency on a DI Container. In this code snippet, even, no DI Container is used.
In this last code snippet, I demonstrated the composition of object graphs using a concept called Pure DI, which basically means practicing DI without the use of a DI Container. Whether to use Pure DI or a DI Container is a topic of its own (which Mark Seemann and I wrote extensively about in chapter 12 of our book), but the main reason for me to show this example is because showing the construction of hand-wired object graphs helps demystifying the concept of DI.
But the main point here is that you should build up deep and complete object graphs of all components in the application inside your Composition Root. Whether you do this by hand (thus Pure DI as the previous example shows) or using a DI Container is up to you.