You can understand the Dependency Inversion Principle so it is helpful before initiating Dependency Injection, it gives us the guidelines for loosely-coupled classes.
- Low level modules should depend on high-level modules and both are depending on abstractions.
- The details should depend upon abstractions but abstractions should not depend upon details.
This is actually mechanism of you can use to make higher-level modules that depends on abstraction.You can create a class of MyDependency and create a Message method in Asp.Net Core.
Example:
publicclassMyDependency
{
publicvoidMessage (string message)
{
Console.WriteLine($"My Dependency.Message called. Message: {message} ");
}
}
In the MyDependency.cs file, you can add another class, IndexModel and derived to PageModel and create a variable name of MyDependency. Create a new method of OnGet in this method you will pass theMydependency method.
Example:
publicclassIndexModel: PageModel
{
privatereadonlyMyDependency _dependency = newMyDependency ();
publicvoidOnGet ()
{
_dependency.Message("Indexmodel.OnGet created this message. ");
}
}
The IndexModel class creates and directly depends on the MyDependency. In the above example, there are following reasons we should avoid.
- The IndexModel class must be modified and Mydependency replace with different implementation.
- The MyDependency must be configured by IndexModel class. If a large project MyDependency class is depends by multiple class. It becomes scattered across the app.
These are problems throughDependency Injection:
- The Dependency implementation use of an interface or base class to abstract in Dependency Injection.
- Asp.Net Core provides built-in service provider that is IServiceProvider. If you add class it will offer services, always registered in the Startup.ConfigureServices method.
You can create interface IDependency and method, Message creates.
Example:
publicinterfaceIDependency
{
voidMessage(string message);
}
In MyDependency, you applied to the interface.
Example:
publicclassMyDependency :IDependency
{
publicvoidMessage(string message)
{
Console.WriteLine($"My Dependency.Message called. Message: {message}");
}
}
Now you can add this class in Startup.ConfigureServices method.
Example:
publicvoidConfigureServices(IServiceCollection services)
{
services.AddScoped();
Example:
publicclassIndex2Model: PageModel
{
privatereadonlyIDependency _dependency;
publicIndex2Model (IDependency dependency)
{
_dependency = dependency;
}
publicvoidOnGet ()
{
_dependency.Message("Working");
}
}
The DI Pattern using in the controller.
- You can only use the IDependency interface, where type is a concrete type of MyDependency. It makeschanges to implementation so easily and controller use it without modifying the controller.
- You cannot create an instance of MyDependency, it`s in by default created DI container.
An implementation of interfaceIDependency can be improved by using the built-in logging API.
Example:
publicclassDependency2 :IDependency
{
privatereadonlyILogger _logger;
publicDependency2(ILogger logger)
{
_logger = logger;
}
publicvoidMessage(string message)
{
_logger.LogInformation($"Dependency method created Mesaage:{message}");
}
}
This code updated the ConfigureServices method and registers new IDependency implement.
Example:
publicvoidConfigureServices(IServiceCollection services)
{
services.AddScoped();
services.AddRazorPages();
}
Dependency2 depends on ILogger,This requestis calledthe constructor. It is a Framework-provided service.
ILogger is not unfamiliar to use Dependency Injection which is chained function. Every dependency requested in turn on its own dependencies request. The set of dependencies are collective that must be resolved typically and referred to as a dependency tree, dependency graph, or object graph.
In the container it resolves ILogger by taking advantage of generic open types, every generic constructed type is needed eliminating.
Dependency Injection terminology in a service.
- IDependency service is typically an object that provides a service to other objects.
- The web service is not related, although the service may use a web service.
Example:
publicclassDisplayModel :PageModel
{
privatereadonlyILogger _logger;
publicDisplayModel(ILogger logger)
{
_logger = logger;
}
publicstring Message { get; set; }
publicvoidOnGet()
{
Message = $"Display Page visited at {DateTime.UtcNow.ToLongTimeString() }";
_logger.LogInformation(Message);
}
}
In this above code, you do not need to update in ConfigureServices, because logging is provided by the framework.