Dependency injection dotnet core achieved with the use of: 1 Basic Concepts

About Microsoft Extension: DependencyInjection has introduced a lot, but most of the emphasis on the realization of the principles and some specific implementation scenario. As the cornerstone dotnet core of the core, where it prepared a comprehensive presentation of concepts, principles and use.

Here first introduced the concept of parts.

1. Concept

The project's GitHub address: https://github.com/aspnet/Extensions/tree/master/src/DependencyInjection

Microsoft.Extensions.DependencyInjectionIt is Microsoft's implementation of the Dependency Inversion principle. As the cornerstone of ASP.NET Core, DependencyInjectionthroughout all aspects of the project, to master its use and principles, not only is important for understanding ASP.NET Core, also it helps to apply it to the development of other projects to help provide project the development efficiency and quality.

Scene 1.1 problem

In software development, projects often have a number of different modules, dependencies between modules. For example, we consider a simplified scenario, we have three categories of user:

  1. AccountController, provide a user interface

  2. UserService, provides the business logic user management

  3. UserRepository, to provide data access to user management

AccountControllerInternal need UserServiceinstance to manage user, while UserServicethe inside is based on the need UserRepositoryto provide data access. We call dependencies between them. Alternatively expressed, AccountControllerdependent on UserService, and UserServicerely on UserRepository. The dependency injection is a powerful tool to help us achieve our dependency management.

1.2 Dependency Inversion Principle DIP

Dependency Inversion principle is one of the well-known design principles, the principle is the theoretical cornerstone of software projects decoupling module.

Defined principles are as follows:

High level modules should not depend upon low level modules,Both should depend upon abstractions.Abstractions should not depend upon details.Details should depend upon abstracts.

Translated as:

  • High-level modules should not depend on low-level modules, both of which should rely on abstract

  • Abstract should not rely on the details

  • Details should depend abstract

In the absence of realization of the principle of dependency inversion, we passed in AccountControllerclass by themselves newto create its dependence on key UserServiceobject instance,

public class AccountController {
​
    private readonly UserService _userService;
    public AccountController() {
        this._userService = new UserService();
    }
}

 

This has led to tight coupling between the two classes, AccountControllerand UserServiceis bound together to create each AccountControllertime, will create an UserServiceobject instance, and if we need to test AccountControllertime, will have to consider UserServicesuch a dependent class level down, UserServicewill depend on UserRepository, you will find classes in your project are bound together tightly coupled, difficult to split.

Based on the principle of dependency inversion usually consider isolation through the interface. For example, we might define a user interface to services:

public  interface IUserService 
{   
}

 

The customer service will implement the interface

public class UserService : IUserService {
}

 

In AccountControllerclass, the change became based interface to use UserService.

public class AccountController {
​
    private readonly IUserService _userService;
    public AccountController() {
        this._userService = new UserService();
    }
}

 

While HomeControllerinside, we can interface-based programming, but this approach does not solve by yourself newto get the UserServiceproblem object instance.

1.3 Inversion of Control IoC

IoCDIP is a well-known design patterns to achieve.

Its core idea is: when needed object instance, do not always consider themselves through newto create the object, put down the process of creating dependent objects, but to create an object to be responsible for the work to someone else, the people we usually called container ( Container) or service provider (ServiceProvider) , we use this later ServiceProviderto refer to it,

From this object instance when needed ServiceProviderget in.

The following is a schematic diagram of a widely used. Take always bring, but from their own wear becomes for you to wear

The inversion of control, the introduction of a  ServiceProvider to help us get object instance .

 

1.4 Dependency injection DI (DependencyInjection)

DI is an implementation of IoC pattern.

《Expert one on one J2EE Development without EJB》第 6 章

Main way to achieve IoC in two ways: dependent lookup, dependency injection (p128)

Dependency injection is a more desirable way. (P130)

Martin Fowler's original text:

As a result I think we need a more specific name for this pattern. Inversion of Control is too generic a term, and thus people find it confusing. As a result with a lot of discussion with various IoC advocates we settled on the name Dependency Injection.

To the effect that:

Already exists a certain mode, which is called IoC, but IoC too broadly, any IoC frameworks, in order to allow ideographic more clearly, decided to use DI to precise allegations it.

There are multiple implementations of the DI, we presented here is DependencyInjection Microsoft official in the Microsoft Extension built to offer. It is IoC in an implementation, the entire core ASP.NET Core-based to achieve it. At the same time, we can also be used in other projects, in order to achieve support for the Dependency Inversion principle.

2. DependencyInjection basic concepts of

2.1 Service Description collection ServiceCollection

Microsoft's DI implementation, all services need to be registered to a common description of the collection service, the DI for the entire collection, the only one, serving only need to register once in this collection, you can later by DI provided to the user.

Interface defines the collection as can be seen, it is actually used to save a set of services registered.IServiceCollection

public interface IServiceCollection : IList<ServiceDescriptor>, ICollection<ServiceDescriptor>, IEnumerable<ServiceDescriptor>, IEnumerable
{
}

 

The default has achieved one pair IServiceCollectionof realization called . In ASP.NET Core, the interior creates an instance of the object, we can also in other projects, to create its own, very simple, straight out ready for use.ServiceCollectionnew

IServiceCollection services = new ServiceCollection ();

 

2.2 Service Service

In DI context, especially by the service object instance DI container management. This service does not have to be called ** Service, but can be any object managed by the DI, DI is only in this context, we will be collectively referred to as service.

Service is our own definition, such as the previously mentioned AccountControllerand UserServiceso on.

We get to serve instance, life cycle management service object through DI, for complex objects exist dependencies, DI also manages dependencies between these instances.

Services must first register in order to use the DI, however, pre-registration and decisions need to consider the life cycle of services.

2.3 Life Cycle Service

Service object instance has a different type of life cycle. Some of the life cycle of an object with the same application, created when the application starts, to be released only when the application exits. For example, our data access object instance. Some objects only used in the current method, after the end of the method call should be destroyed. Lifecycle management services used to manage these needs.

DI supports three types of life cycle:

  1. Singleton, singleton, only one instance in the current application environment. Services such as data access object instance.

  2. Scoped, limited range, once out of this range, in this range of service objects need to be destroyed. For example, Web development request object instance.

  3. Transient, transient, one-time use, each obtained from the DI, return a new instance.

Microsoft.Extensions.DependencyInjection.ServiceLifetime

public enum ServiceLifetime
{
    Singleton,
    Scoped,
    Transient
}

 

Lifecycle Services is determined at the time of registration services. When in use, direct access to instance, no longer designated lifecycle services. Microsoft offers a variety of ways to facilitate the expansion of services specified in the registration service lifecycle. Here, for example, the life cycle is specified by the single generic way of embodiment modes.

// based interface register 
services.AddSingleton <IUserService, UserService> () ;

 

2.4 Service Provider ServiceProvider

Not get to use the service when needed from the set of object instances registration service, but need to get through the service provider, the service provider is a clear need from the set of registered services. Service provider interface defined , it is one of the basic definition of .net, not defined in the DI framework.IServiceProvider

public interface IServiceProvider
{
    object GetService(Type serviceType);
}

 

The DI expanded to provide support for the service provider to obtain the ServiceProvider.ServiceCollectionContainerBuilderExtensionsIServiceCollection

public static ServiceProvider BuildServiceProvider(this IServiceCollection services)
{
    return BuildServiceProvider(services, ServiceProviderOptions.Default);
}

 

So, we usually use this method to obtain and use it.

// create a registration service container 
IServiceCollection Services = new new ServiceCollection ();
 // registration service, here designated single embodiment 
services.AddSingleton <IUserService, UserService> ();
 // get the service provider through the vessel 
IServiceProvider provider = services.BuildServiceProvider ();

 

2.5 object instance access to services

By the service provider to obtain service manual object instance. By type of service registration, direct call GetServicemethod can be.

For example, in front of us signed up for the type of service IUserServiceimplementation type is UserService, you can get to the actual instance of the object that implements this interface by means of this type.

// create a registration service container 
IServiceCollection Services = new new ServiceCollection ();
 // registration service, here designated single embodiment 
services.AddSingleton <IUserService, UserService> ();
 // get the service provider through the vessel 
the IServiceProvider Provider = services.BuildServiceProvider ();
 // Get the service object through the interface instance 
IUserService instance = provider.GetService <IUserService> ( );

 

It seems more complicated. In actual use, we rarely use such a way to use DI, later we go any further specific use.

 

Guess you like

Origin www.cnblogs.com/haogj/p/11370314.html