- Java锁的逻辑(结合对象头和ObjectMonitor)
- 还在用饼状图?来瞧瞧这些炫酷的百分比可视化新图形(附代码实现)⛵
- 自动注册实体类到EntityFrameworkCore上下文,并适配ABP及ABPVNext
- 基于Sklearn机器学习代码实战
ASP.NET Core 支持依赖关系注入 (DI) 软件设计模式,这是一种在类及其依赖关系之间实现 控制反转 (IoC) 的技术。 按照官方文档的描述: 依赖关系注入通过以下方式解决了这些问题:
在asp.net core中,以来注入有三个生命周期。 分别为Singleton(单例),Scoped(范围),Transient(瞬态)。 Singleton(单例),很好理解,就是一个单例模式,在整个应用的生命周期中只会初始化一次。 Scoped(范围),每一次请求中实例化一次。 Transient(瞬态),每次使用都是一个新的实例化对象。 注入方式分别如下:
services.AddSingleton(); //单例
services.AddScoped(); //范围
services.AddTransient(); //瞬态
来实践一下,用VS新建一个WebApi项目,然后添加三个类,对应三个生命周期.
public class TestTransient
{
public TestTransient()
{
Id = Guid.NewGuid();
}
public Guid Id { get; set; }
}
public class TestSingleton
{
public TestSingleton()
{
Id = Guid.NewGuid();
}
public Guid Id { get; set; }
}
public class TestScoped
{
public TestScoped()
{
Id = Guid.NewGuid();
}
public Guid Id { get; set; }
}
然后在Program中添加注入,这里我没用接口注入,直接注入类,我们也可以使用接口注入的方式.
builder.Services.AddSingleton<TestSingleton>();
builder.Services.AddScoped<TestScoped>();
builder.Services.AddTransient<TestTransient>();
接下来我们在控制器中通过构造函数注入我们的三个类.
private readonly ILogger<WeatherForecastController> _logger;
private readonly TestScoped _testScoped;
private readonly TestSingleton _testSingleton;
private readonly TestTransient _testTransient;
public WeatherForecastController(ILogger<WeatherForecastController> logger, TestScoped testScoped, TestSingleton testSingleton, TestTransient testTransient)
{
_logger = logger;
_testScoped = testScoped;
_testSingleton = testSingleton;
_testTransient = testTransient;
}
在调用Get方法中打印我们的Id 第一次请求 第二第三次请求 可以看到单例的Id每次请求都是一致的,而范围和瞬态的在不同请求中都不一样。 那么如何区别Scoped和Transient呢?很简单,我们直接整一个简单的中间件,分别注入并答应对应Id.
app.Use(async (httpContext, next) =>
{
var scoped = httpContext.RequestServices.GetRequiredService<TestScoped>();
var transient = httpContext.RequestServices.GetRequiredService<TestTransient>();
Console.WriteLine($"Middleware scoped: {scoped.Id}");
Console.WriteLine($"Middleware transient: {transient.Id}");
await next(httpContext);
});
可以看到,在一次请求中Scoped的Id是一致的,Transient的Id每次都不一样.
在上面中我只是用了其中一种注册方法,就是直接注册类。 除此之外,我们还可以通过接口注入。 比如我们添加一个IScopedDependency的接口,然后新建一个TestAbcScoped继承IScopedDependency,然后在Program中添加注入 。
builder.Services.AddScoped<IScopedDependency, TestAbcScoped>();
之后我们在构造器中使用IScopedDependency注入的话,则自动会获得TestAbcScoped的实现实例。 通过我们Debug监视,可以发现IScopedDependency注入的实例确实是TestAbcScoped。 当我们注册同一个接口的多个实现时,默认取最后一次注入的实例,当我们需要获取全部接口的实现时,可以通过注入IEnumerable 获取该接口的所有实现。 我们增加一个IScopedDependency的实现 。
public class TestAbcScoped : IScopedDependency
{
}
public class TestAbcdScoped : IScopedDependency
{
}
注册顺序为:
builder.Services.AddScoped<IScopedDependency, TestAbcScoped>();
builder.Services.AddScoped<IScopedDependency, TestAbcdScoped>();
可以看到,单个注入会取后注入的实例,IEnumerable注入则会获取所有的实例。 注意: 除此之外,还有TryAddXXX的方法,注册服务时,如果还没有添加相同类型的实例,就添加一个实例。 服务注册通常与顺序无关,除了注册同一类型的多个实现时.
上面我们实操时所用的注入方法都是构造器注入,这也是官方推荐的注入方式。 除此之外,我们还可以使用IServiceProvider获取服务,上面中间件所用到的HttpContext.RequestService本质是一个IServiceProvider实例。 三方框架加持注入功能,asp.net core的注入方式有限,我们可以使用Autofac来增强。 使用autofac之后我们可以支持属性注入,即无需在构造器中添加,只需要构造对应的属性即可。 属性注入和构造器注入的优缺点对比。 构造器注入可以清晰的看出我们所有注入的实例,对于协作和沟通有比较大的帮助。但是,若是注入的东西太多,会导致一个很庞大的构造器,当然官方的建议是,当存在那么多的注入的时候,就需要考虑拆分业务了。 属性注入则只需要通过构造一个属性,系统自动注入,弱点是没有构造器清晰辨别。毕竟不容易区分哪些属性是通过注入的,哪些是业务赋值的。 在考虑到继承方面时,有时候属性注入会比构造器注入合适,比如在基类中,我们往往可以注入通用的服务,这样在子类的构造器中就无需再次注入该服务.
在使用依赖注入的时候,我们最好要明确每个服务的生命周期,在长生命周期的服务中,切勿注入短生命周期的服务。 如在单例中注入范围服务或瞬时服务,在范围服务中注入瞬时服务。否则会出现对象已被释放的情况。 在新版本中,单例里面注入范围服务,程序会自动检测并提示异常。但是在旧版本中是没有提示的,这点需要注意.
如何在单例中使用Scoped范围服务呢,可以使用IServiceScopeFactory,IServiceScopeFactory始终注册为单例实例,通过IServiceScopeFactory创建一个Scope生命周期.
public class TestSingleton
{
private readonly IServiceScopeFactory _serviceScopeFactory;
public TestSingleton(IServiceScopeFactory serviceScopeFactory)
{
_serviceScopeFactory = serviceScopeFactory;
Id = Guid.NewGuid();
}
public Guid Id { get; set; }
public void Console()
{
using(var scope = _serviceScopeFactory.CreateScope())
{
var testScoped = scope.ServiceProvider.GetRequiredService<TestScoped>();
System.Console.WriteLine($"TestSingleton - TestScoped: {testScoped.Id}");
}
}
}
再次启动服务正常,并且请求可以看到,我们CreateScope后,生成的Id也是跟请求中的Scoped不一样的,因为他们属于不同的Scoped.
欢迎进群催更.
最后此篇关于asp.netcore之依赖注入的文章就讲到这里了,如果你想了解更多关于asp.netcore之依赖注入的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
在一个新的 ASP.NET Core RC2 类库中,我有以下 project.json 文件,我试图在其中遵循 How to trim your package dependencies 上的文档.
我在本地提要上将 nuget 包从 2.2.x 更新到 3.1.0。 然后,在构建机器上尝试构建项目,但是: Project.csproj(0,0): Error NU1102: Unable to
什么是Kafka Apache Kafka是一个分布式流处理平台,由LinkedIn开发并开源,后来成为Apache软件基金会的顶级项目。Kafka主要用于构建实时数据管道和流式应用程序。
快递100的物流信息查询接口,官方提供了一些demo;还好官方提供的代码是.netcore版本写的,不过写的有点low;根据官方提供的代码,我按照.netcore 的风格重构了代码;核心代码如下:
1、docker介绍 docker是用go语言编写基于linux操作系统的一些特性开发的,其提供了操作系统级别的抽象,是一种容器管理技术,它隔离了应用程序对基础架构(操作系统等)的依赖。相较于虚
demo运行在windows的docker中,系统是win10,所以需要先下载docker for windows,安装完毕后系统会重启,然后桌面上可以找到docker for windows的快捷
NetCore WebSocket 即时通讯示例,供大家参考,具体内容如下 1.新建Netcore Web项目 2.创建简易通讯协议 ?
.NET Core:架构、特性和优势详解 在软件开发领域,保持领先地位至关重要。随着技术以指数级的速度发展,开发人员不断寻求高效、可扩展且多功能的解决方案来应对现代挑战。.NET Core 就是这样
需求场景: 我需要部署的项目是在Windows上开发的,目标框架为.net core 6.0 因此我们需要先在kylin上部署项目运行所需要的环境。 借助百
我正在 .NET Core 中重写一个调用外部 Web 服务的控制台应用程序。 我目前收到以下错误: One or more errors occurred. (The HTTP request is
关闭。此题需要details or clarity 。目前不接受答案。 想要改进这个问题吗?通过 editing this post 添加详细信息并澄清问题. 已关闭 6 年前。 Improve th
我有一组库,我想将其从 PCL 转移到 netcore。通过此举,我想简化 DI 系统并更新一些内部工作方式。 我想添加的其中一件事是内部对象的配置,就像在 Asp.Net Core 中一样(即 se
注:本文隶属于《理解ASP.NET Core》系列文章,请查看置顶博客或 点击此处查看全文目录 概述 在微服务化的架构设计中,网关扮演着重要的看门人角色,它所提供的功能之一
对于有多个应用系统的企业来说,每一个应用系统都有自己的用户体系,这就造成用户在切换不同应用系统时,就要多次输入账号密码,导致体验非常不好,也造成使用上非常不便。 针对这个问题,我们就可以采用单
就像 Web Api 接口可以对入参进行验证,避免用户传入非法的或者不符合我们预期的参数一样,选项也可以对配置源的内容进行验证,避免配置中的值与选项类中的属性不对应或者不满足预期,毕竟大部分配置
.NET Core 选项系统的主要实现在 Microsoft.Extensions.Options 和 Microsoft.Extensions.Options.ConfigurationExten
漏洞说明: 跨站脚本攻击(Cross Site Scripting),为了不和层叠样式表(Cascading Style Sheets, CSS)的缩写混淆,故将跨站脚本攻击缩写为XSS。恶意攻击
分布式缓存是由多个应用服务器共享的缓存,通常作为访问它的应用服务器的外部服务进行维护。 分布式缓存可以提高 ASP.NET Core 应用的性能和可伸缩性,尤其是当应用由云服务或服务器场托管时。
一个应用要运行起来,往往需要读取很多的预设好的配置信息,根据约定好的信息或方式执行一定的行为。 配置的本质就是软件运行的参数,在一个软件实现中需要的参数非常多,如果我们以 Hard Code(
2. 配置添加 配置系统可以读取到配置文件中的信息,那必然有某个地方可以将配置文件添加到配置系统中。之前的文章中讲到 ASP.NET Core 入口文件中,builder(WebApplica
我是一名优秀的程序员,十分优秀!