依赖注入在 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 的实例,它才会实例化。
依赖注入在 dotnet core 中实现与使用:3 使用 Lazy<T> 延迟实例化的更多相关文章
- 依赖注入在 dotnet core 中实现与使用:1 基本概念
关于 Microsoft Extension: DependencyInjection 的介绍已经很多,但是多数偏重于实现原理和一些特定的实现场景.作为 dotnet core 的核心基石,这里准备全 ...
- 依赖注入在 dotnet core 中实现与使用:2 使用 Extensions DependencyInjection
既然是依赖注入容器,必然会涉及到服务的注册,获取服务实例,管理作用域,服务注入这四个方面. 服务注册涉及如何将我们的定义的服务注册到容器中.这通常是实际开发中使用容器的第一步,而容器本身通常是由框架来 ...
- 依赖注入在 dotnet core 中实现与使用:4. 集成 Autofac
本示例使用 .net core 5 rc-1 实现. 1. 添加 Nuget 包引用 使用 Autofac 当然要添加 Autofac 的 Nuget 包,主要涉及到两个: Autofac.Exten ...
- Dotnet Core中使用AutoMapper
官网:http://automapper.org/ 文档:https://automapper.readthedocs.io/en/latest/index.html GitHub:https://g ...
- 依赖注入[8]: .NET Core DI框架[服务消费]
包含服务注册信息的IServiceCollection对象最终被用来创建作为DI容器的IServiceProvider对象.当需要消费某个服务实例的时候,我们只需要指定服务类型调用IServicePr ...
- 依赖注入[7]: .NET Core DI框架[服务注册]
包含服务注册信息的IServiceCollection对象最终被用来创建作为DI容器的IServiceProvider对象.服务注册就是创建出现相应的ServiceDescriptor对象并将其添加到 ...
- 依赖注入[6]: .NET Core DI框架[编程体验]
毫不夸张地说,整个ASP.NET Core框架是建立在一个依赖注入框架之上的,它在应用启动时构建请求处理管道过程中,以及利用该管道处理每个请求过程中使用到的服务对象均来源于DI容器.该DI容器不仅为A ...
- .NET CORE学习笔记系列(2)——依赖注入[7]: .NET Core DI框架[服务注册]
原文https://www.cnblogs.com/artech/p/net-core-di-07.html 包含服务注册信息的IServiceCollection对象最终被用来创建作为DI容器的IS ...
- .NET CORE学习笔记系列(2)——依赖注入[6]: .NET Core DI框架[编程体验]
原文https://www.cnblogs.com/artech/p/net-core-di-06.html 毫不夸张地说,整个ASP.NET Core框架是建立在一个依赖注入框架之上的,它在应用启动 ...
随机推荐
- 【安富莱】V6,V5开发板用户手册,重在BSP驱动包设计方法,HAL库的框架学习,授人以渔(2019-11-04)
说明: 1.本教程重在BSP驱动包设计方法和HAL库的框架学习,并将HAL库里面的各种弯弯绕捋顺,从而方便我们的程序设计. 2.本次工程延续以往的代码风格,从底层BSP驱动包到应用代码,变量命名,文件 ...
- Spark家族:Win10系统下搭建Scala开发环境
一.Scala环境基础 Scala对Java相关的类,接口进行了包装,所以依赖Jvm环境. Jdk 1.8 scala 依赖 scala 2.11 安装版本 idea 2017.3 开发工具 二.配置 ...
- 动态数组原理【Java实现】(六)
前言 接下来我们进入集合学习,看过很多文章一上来就是讲解原理感觉会特别枯燥,任何成熟解决方案的出现都是为了解决问题,若通过实际问题引入然后再来讲解原理想必学起来必定事半功倍,从我写博客的那一天起,我就 ...
- linux创建用户并锁定用户目录和首次登陆强制修改密码
1. 创建用户及访问目录 mkdir -p /home/user/testuser 创建用户目录 useradd testuser -d /home/user/testuser -M ...
- netcore3.0配置跨域
netcore3.0框架已集成了Microsoft.AspNetCore.Mvc.Cors包,因此不需要单独引用. 在ConfigureServices中添加Cors策略服务 services.Add ...
- HTML中特殊符号编码对照表,html特殊符号编码都有哪些?
HTML中一些无法打出来的符号可以用相应的代码进行代替显示,本文提供了一些HTML特殊符号相应的代码供开发者参考. 特殊符号 命名实体 十进制编码 特殊符号 命名实体 十进制编码 特殊符号 命名实体 ...
- Java日期处理组件joda-time
版权声明:本文为xing_star原创文章,转载请注明出处! 本文同步自http://javaexception.com/archives/175 Java日期处理组件joda-time 平常在开发过 ...
- 【转】java中使用WebSocket
传统的请求,都是从客服端到服务端,表现在web应用上就是,消息都只能由浏览器发起请求,调用客户端的方法. webSocket可以从服务器端推送消息给浏览器. 使用场景: 当客户端发起缴费请求时,由服务 ...
- [转载] Java 遍历 Map 的 5 种方式
目录 1 通过 keySet() 或 values() 方法遍历 2 通过 keySet 的 get(key) 获取值 3 通过 entrySet 遍历 4 通过迭代器 Iterator 遍历 5 通 ...
- 用while循环写一个简单的猜数字游戏
import random #练习:模拟猜数字的游戏 """ 计算机出一个1~100之间的随机数由人来猜 计算机根据人猜的数字分别给出 大一点/小一点/猜中了 的提示 & ...