依赖注入在 dotnet core 中实现与使用:3 使用 Lazy<T> 延迟实例化

有些对象我们并不想一开始就实例化,由于性能或者功能的考虑,希望等到使用的时候再实例化。
考虑存在一个类 A, 它使用了依赖的类 B,在 A 中,只有某些不常用到的方法会涉及调用 B 中的方法,多数情况下,并不使用这个 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 }
    }
}

把它们注册到容器中,然后使用一下。

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();
    }
}

这里仅仅调用了类 A 的 MethodTwo() 和 MethodThree() 这两个方法,那么,对于类 B 的实例化就是没有必要的。但是,从输出中可以看到,由于类 A 依赖了类 B,所以,B 被提前实例化了。

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

在这种情况下,如何可以避免对类 B 的实例化呢?考虑使用 Lazy<T> 。

当通过 Lazy<T> 的方式注入依赖的类型的时候,我们将延迟了对所依赖对象的构造,而且,Lazy<T> 会被自动注入,与使用注册在容器中的 T 一样。

Layz<T> 表示在第一次访问的时候才会初始化的值。上面的代码可以修改为如下形式:

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 }
    }
}

注册的形式也需要调整一下。

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();
}

对类型 B 的注册,变成了注册 Lazy<B>。它是 B 的一个封装。

现在重新运行程序,可以看到如下的结果。

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

在调用 MethodTwo() 和 MethodThree() 的时候,类型 B 并没有实例化,直到实际调用 MethodOne() 的时候,实际访问了类型 B 的实例,它才会实例化。

原文地址:https://www.cnblogs.com/haogj/p/11450422.html

时间: 2024-10-31 18:13:48

依赖注入在 dotnet core 中实现与使用:3 使用 Lazy<T> 延迟实例化的相关文章

依赖注入在 dotnet core 中实现与使用:1 基本概念

关于 Microsoft Extension: DependencyInjection 的介绍已经很多,但是多数偏重于实现原理和一些特定的实现场景.作为 dotnet core 的核心基石,这里准备全面介绍它的概念.原理和使用. 这里首先介绍概念部分. 1. 概念 该项目在 GitHub 的地址:https://github.com/aspnet/Extensions/tree/master/src/DependencyInjection Microsoft.Extensions.Depende

spring的依赖注入【NC产品中也用到spring的依赖注入】

下面设计到的类有EditPsndocAction跟RefreshPsndocAction这个两个类, 而我想要的最终效果是: 下面解释一下流程“ 如下图所示:因为NC产品中使用了spring的的依赖注入.所以我这里可以这样子调用.直接调用定刷新按钮的bean . 在EditPsndocAction这个类中,用spring的依赖注入的一个方式.给对象赋值 注意一点就是:RefreshPsndocAction 是刷新按钮对应的ben的名称.也就是 最后在EdictPsndocAction这个类的do

dotnet core 中数值溢出

.net core中使用C#的int类型,存在数值上下限范围,如下: int max = int.MaxValue; int min = int.MinValue; Console.WriteLine($"The range of integers is {min} to {max}"); 运行得到结果 The range of integers is -2147483648 to 2147483647 此时如果执行以下代码 int what = max + 3; Console.Wr

ASP.NET Core依赖注入——依赖注入最佳实践

在这篇文章中,我们将深入研究.NET Core和ASP.NET Core MVC中的依赖注入,将介绍几乎所有可能的选项,依赖注入是ASP.Net Core的核心,我将分享在ASP.Net Core应用中使用依赖注入的一些经验和建议,并且将会讨论这些原则背后的动机是什么: (1)有效地设计服务及其依赖关系. (2)防止多线程问题. (3)防止内存泄漏. (4)防止潜在的错误. 在讨论该话题之前,了解什么是服务是生命周期至关重要,当组件通过依赖注入请求另一个组件时,它接收的实例是否对该组件实例是唯一

ASP.NET Core中使用GraphQL - 第六章 使用EF Core作为持久化仓储

ASP.NET Core中使用GraphQL ASP.NET Core中使用GraphQL - 第一章 Hello World ASP.NET Core中使用GraphQL - 第二章 中间件 ASP.NET Core中使用GraphQL - 第三章 依赖注入 ASP.NET Core中使用GraphQL - 第四章 GrahpiQL ASP.NET Core中使用GraphQL - 第五章 字段, 参数, 变量 本篇中我将演示如何配置持久化仓储,这里原文中是使用的Postgres, 这里我改用

ASP.NET Core中使用GraphQL - 第八章 在GraphQL中处理一对多关系

ASP.NET Core中使用GraphQL - 目录 ASP.NET Core中使用GraphQL - 第一章 Hello World ASP.NET Core中使用GraphQL - 第二章 中间件 ASP.NET Core中使用GraphQL - 第三章 依赖注入 ASP.NET Core中使用GraphQL - 第四章 GrahpiQL ASP.NET Core中使用GraphQL - 第五章 字段, 参数, 变量 ASP.NET Core中使用GraphQL - 第六章 使用EF Co

ASP.NET Core中使用GraphQL - 第五章 字段, 参数, 变量

ASP.NET Core中使用GraphQL ASP.NET Core中使用GraphQL - 第一章 Hello World ASP.NET Core中使用GraphQL - 第二章 中间件 ASP.NET Core中使用GraphQL - 第三章 依赖注入 ASP.NET Core中使用GraphQL - 第四章 GrahpiQL 字段# 我们已经很好的理解了GraphQL中的字段.在之前HelloWorldQuery的例子中,我们添加了2个字段hello和howdy. 它们都是标量字段.正

ASP.NET Core 依赖注入基本用法

ASP.NET Core 依赖注入 ASP.NET Core从框架层对依赖注入提供支持.也就是说,如果你不了解依赖注入,将很难适应 ASP.NET Core的开发模式.本文将介绍依赖注入的基本概念,并结合代码演示如何在 ASP.NET Core中使用依赖注入. 什么是依赖注入? 百度百科对于依赖注入的介绍: 控制反转(Inversion of Control,缩写为IoC),是面向对象编程中的一种设计原则,可以用来减低计算机代码之间的耦合度.其中最常见的方式叫做依赖注入(Dependency I

NET Core,你必须了解无处不在的“依赖注入”

NET Core,你必须了解无处不在的“依赖注入” ASP.NET Core的核心是通过一个Server和若干注册的Middleware构成的管道,不论是管道自身的构建,还是Server和Middleware自身的实现,以及构建在这个管道的应用,都需要相应的服务提供支持,ASP.NET Core自身提供了一个DI容器来实现针对服务的注册和消费.换句话说,不只是ASP.NET Core底层框架使用的服务是由这个DI容器来注册和提供,应用级别的服务的注册和提供也需要以来这个DI容器,所以正如本文标题