.NET Core ASP.NET Core Basic 1-2 inversion of control and dependency injection

.NET Core ASP.NET Core Basic 1-2

This section of the control and dependency inversion injection

Brief introduction

Inversion of Control IOC

The fact that the content in our advanced version of C # has been explained, Inversion of Control is a design pattern, you can understand inversion of control, consider a man he has an A brand mobile phones, he performed songs using a mobile phone, playing games, then you can create a mobile phone and a human class

class APhone : IPhone
{
    public string Owner{get;set;}
    public Phone(string own)
    {
        Owner = own;
    }
    void Play()
    {
        //省略
    }
    void Music()
    {
        //省略
    }
}
class Man
{
    public string Name{get;set;}
    void Game()
    {
        var p = new APhone(Name);
        p.Play();
    }
}

In fact the coupling of this code is relatively high? It uses forward, that is when I need something, I created a this thing myself. Why only the B brand after him wrong about this, if one day the man decided not to use the A-brand mobile phone, he decided. Then it means that the entire class Man used local APhone class needs to be changed. This is a very troublesome thing, this time we need to exercise our control IOC reversed. We will create an instance of an object or to require the use of your caller is responsible only for its own use, you rely on other people threw understanding of this process is injected.

The core is the Inversion of Control - otherwise I keep using my own stuff, and now I give control to my superiors, I need to use him again. This time, the role of the interface is self-evident, A Phone interfaces inherited, B also inherited, suppose we start out with a Phone to create different interfaces A, B objects, it is not effective to switch AB objects?

Dependency Injection

Dependency injection is a reflect of IOC (Inversion of Control), it is very simple, Man class code used in our previous way forward is, is I want an object, then I would create one. Now we use dependency injection is to our control of this object to the upper-level interface that has become this, I want an object, I would make a request to their superiors, superiors gave me create an object. We usually use dependency injection constructor injection way.

Code above will become

class Man
{
    private readonly IPhone _phone;
    public Man(IPhone phone)
    {
        _phone = phone;
    }
}

Assuming that this time you need to replace your phone brand B, then injected just need a place to pass the object B brand.

container

But now there is a new problem, assuming that said the class has 100 using the interface dependent, if we are not to do such a thing in 100 places? Control is reversed, dependent also handed over to create the outside. The question now is dependent on too much, we need a unified management system in place all the dependencies, this time, we will use the container for centralized management

Container is responsible for two things:

  • And the binding relationship between the service instance
  • Gets an instance, and instance management (creation and destruction)

use

Said so much, how we use our dependency on .NET Core injected into it? Here we are for all .NET Core applications, dependency injection in .NET Core core is divided into two components: Located IServiceCollection and IServiceProvider under Microsoft.Extensions.DependencyInjection namespace.

among them

  • IServiceCollection responsible for registering
  • IServiceProvider responsible for providing examples

There are three methods in the default container ServiceCollection

  • .AddTransient<I,C>()
  • .AddSingleton<I,C>()
  • .AddScoped<I,C>()

Here we would have to mention the life cycle of dependency injection of three

  • Singleton referring to a singleton, that is, during the entire operation of the program will generate a
  • Transient means that every GetService will create a new instance
  • Scope Scope refers in the same initialization only one instance, it can be understood as (a request every level to create only one instance, the same http request will be within the scope in a)

We can try to use the console project to simulate the dependency injection principle, which means we get our object instance directly from the container, and we use Guid uniqueness of the mark.

//创建三个代表不同生命周期的接口
    interface IPhoneScope
    {
        Guid Guid { get; }
    }
    interface IPhoneSingleton
    {
        Guid Guid { get; }
    }
    interface IPhoneTransient
    {
        Guid Guid { get; }
    }
    //实现的类
    class PhoneService:IPhoneScope,IPhoneSingleton,IPhoneTransient
    {
        public PhoneService()
        {
            this._guid = Guid.NewGuid();
        }

        public PhoneService(Guid guid)
        {
            this._guid = guid;
        }

        private Guid _guid;

        public Guid Guid => this._guid;
    }

Then, our main function

namespace DI_AND_IOC
{
    class Program
    {
        static void Main(string[] args)
        {
            //注入服务
            var services = new ServiceCollection()
                .AddScoped<IPhoneScope, PhoneService>()
                .AddTransient<IPhoneTransient, PhoneService>()
                .AddSingleton<IPhoneSingleton, PhoneService>();
            //构造服务
            var provider = services.BuildServiceProvider();
            using (var scope = provider.CreateScope())
            {
                var p = scope.ServiceProvider;
                var scopeobj1 = p.GetService<IPhoneScope>();
                var transient1 = p.GetService<IPhoneTransient>();
                var singleton1 = p.GetService<IPhoneSingleton>();

                var scopeobj2 = p.GetService<IPhoneScope>();
                var transient2 = p.GetService<IPhoneTransient>();
                var singleton2 = p.GetService<IPhoneSingleton>();

                Console.WriteLine(
                    $"scope1: {scopeobj1.Guid},\n" +
                    $"transient1: {transient1.Guid}, \n" +
                    $"singleton1: {singleton1.Guid}\n");

                Console.WriteLine($"scope2: {scopeobj2.Guid}, \n" +
                                  $"transient2: {transient2.Guid},\n" +
                                  $"singleton2: {singleton2.Guid}\n");
            }
            //创建不同的scope
            using (var scope = provider.CreateScope())
            {
                var p = scope.ServiceProvider;
                var scopeobj3 = p.GetService<IPhoneScope>();
                var transient3 = p.GetService<IPhoneTransient>();
                var singleton3 = p.GetService<IPhoneSingleton>();
                Console.WriteLine($"scope3: {scopeobj3.Guid}, \n" +
                                  $"transient3: {transient3.Guid},\n" +
                                  $"singleton3: {singleton3.Guid}");
            }
        }
    }
}

You should get something like the following data

scope1: 096d38e5-0c7b-4e50-9c79-241fb18a56ed,
transient1: 289ebd11-8159-4f22-b53e-ed738a317313,
singleton1: b453b7f5-3594-4b66-99c8-a72763abaa83

scope2: 096d38e5-0c7b-4e50-9c79-241fb18a56ed,
transient2: 212ad420-e54c-4dd6-9214-abe91aacdd9c,
singleton2: b453b7f5-3594-4b66-99c8-a72763abaa83

scope3: 688b6ffd-a8c1-47f4-a20a-872c2285d67c,
transient3: 3d09997d-fffb-43d1-9e53-ccf9771c819d,
singleton3: b453b7f5-3594-4b66-99c8-a72763abaa83

Can be found, singleton objects is not going to change, and the scope object is changed after creating a new scope, and transient objects every request in change.

It should be noted that the use of container in the console service projects need to introduce *** Microsoft.Extensions.DependencyInjection *** assemblies, you can import the dll introduced in

By injecting the service life cycle management and control, in some ASP.NET Core project, some class (service) is possible or spans multiple Action Controller, then we correct use of the life cycle, we can save memory as much as possible, that is, examples of initialization can be reduced consumption.

Use of the ASP.NET Core

In ASP.NET Core, we use dependency injection is very simple, ConfigureServices method in StartUp class has been good for us to build a container, we just need to do an operation like this

services.AddScoped<IPhoneScope, PhoneService>();
services.AddDbContext<DbContext>();
services.AddMVC();

If you need to inject services in the controller, the official recommendation is to use constructor injection

public IPhoneScope _ips;
public Controller(IPhoneScope ips)
{
    _ips = ips;
}

In particular, if you use the MVC Razor pages injected, then enter the following command

@inject IPhoneScope  ips

If my post helped you, you github.NETCoreGuide project helped me a star, a concern and recommendation in the garden midpoint blog.

Github

BiliBili Home

WarrenRyan'sBlog

Blog Park

Guess you like

Origin www.cnblogs.com/WarrenRyan/p/11444398.html