Dependency injection implemented with the use dotnet core: 3 using Lazy <T> lazy instantiation

 

Some objects we do not want to instantiate the outset, considering the performance or function, we hope to use the time until then instantiated.
Consider the existence of a class A, which uses the dependent class B, in A, only certain methods are not used to be involved in the method invocation B, in most cases, this example does not use the B.

using System;

public class A {
    private B _b;
    public A (B b) {
        _b = b;
        Console.WriteLine("construct class A...");
    }

    public void MethodOne () {
        _b.ClassBMethod ();
    }

    public void MethodTwo () {
        // does not use _b 
    }

    public void MethodThree () {
        // does not use _b 
    }
}

public class B {

    public B (){
        Console.WriteLine("construct class b......");
    }
    public void ClassBMethod () { //do something } 
    }
}

 

Register them into a container, then use it.

using System;
using Microsoft.Extensions.DependencyInjection;

class Program {
    static void Main (string[] args) {
        IServiceCollection services = new ServiceCollection ();

        services.AddSingleton<B>();
        services.AddSingleton<A>();

        var provider = services.BuildServiceProvider();
        var a = provider.GetService<A>();
        a.MethodTwo();
        a.MethodThree();
    }
}

Here only MethodTwo called class A () and MethodThree () these two methods, then, for instance of class B is not necessary. However, it can be seen from the output, since the class A depends Classes B, therefore, B is instantiated in advance.

construct class b......
construct class A...

 

In this case, how to avoid instances of class B do? Consider using Lazy <T>.

When injecting dependencies by Lazy <T> type manner, we delayed the construction of their dependent objects, and, Lazy <T> is automatically injected, with the use of T registered in the same container.

Layz <T> represents the value at the time of the first visit will be initialized. The code above may be modified as follows:

using System;

public class A {
    private Lazy<B> _b;
    public A (Lazy<B> b) {
        _b = b;
        Console.WriteLine("construct class A...");
    }

    public void MethodOne () {
        _b.Value.ClassBMethod ();
    }

    public void MethodTwo () {
        // does not use _b 
    }

    public void MethodThree () {
        // does not use _b 
    }
}

public class B {

    public B (){
        Console.WriteLine("construct class b......");
    }
    public void ClassBMethod () { //do something } 
    }
}

 

Registration forms also need to adjust.

static void Main (string[] args) {
    IServiceCollection services = new ServiceCollection ();
    
    services.AddSingleton<Lazy<B>>();  
    services.AddSingleton<A>();

    var provider = services.BuildServiceProvider();
    var a = provider.GetService<A>();
    a.MethodTwo();
    a.MethodThree();
    Console.WriteLine("prepare call MethodOne...");
    a.MethodOne();
}

 

Type B registered into the register Lazy <B>. It is a package of B.

Now re-run the program, you can see the following results.

construct class A...
prepare call MethodOne...
construct class b......

 

When calling MethodTwo () and MethodThree (), the type B is not instantiated until the actual call MethodOne () when the actual visit an example of the type B, which will be instantiated.

 

Guess you like

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