[Fact]
public void WhenRegisteredAsForwardedSingleton_InstancesAreTheSame()
var services = new ServiceCollection();
services.AddSingleton<Foo>();
services.AddSingleton<IFoo>(x => x.GetRequiredService<Foo>());
services.AddSingleton<IBar>(x => x.GetRequiredService<Foo>());
var provider = services.BuildServiceProvider();
var foo1 = provider.GetService<Foo>();
var foo2 = provider.GetService<IFoo>();
var foo3 = provider.GetService<IBar>();
Assert.Same(foo1, foo2);
Assert.Same(foo1, foo3);
为了将对接口的请求“转发”到具体类型,您必须做两件事:
- 使用
services.AddSingleton<Foo>()
显式注册具体类型 - 通过提供工厂函数将接口请求委托给具体类型:
services.AddSingleton<IFoo>(x =>x.GetRequiredService<Foo>())
使用这种方法,无论您请求哪个实现的服务,您都将拥有一个真正的 Foo
单例实例。
这种提供“转发”类型的方法已在原始问题中指出,并有一个警告——它不是很有效。通常最好尽可能避免使用“服务定位器样式”GetService()
调用。 但是,我觉得在这种情况下这绝对是更可取的做法。
在这篇文章中,我描述了如果将具体类型注册为 ASP.NET Core DI 服务的多个服务会发生什么。 特别是,我展示了如何最终得到 Singleton
对象的多个副本,这可能会导致细微的错误。 要解决这个问题,您可以在注册时提供服务实例,也可以使用工厂方法委托服务解析。 使用工厂方法不是很有效,但通常是最好的方法。
在本文中,我描述了如何在 ASP.NET Core 中使用的容器中注册具有多个公共接口的具体类。使用这种方法,您将能够使用具体类实现的任何接口来检索具体类。然后您将能够注入或,您将收到相同的实例。以特定方式注册以避免意外的生命周期问题很重要,例如有两个单例实例!在这篇文章中,我简要概述了 ASP.NET Core 中的 DI 容器及其与第三方容器相比的一些限制。然后,我将描述将对多个接口的请求“转发”到具体类型的概念,以及如何使用 ASP.NET Core DI 容器实现此目的。
此文是在官方文档的基础上做的个人笔记,一些简单的内容就没用再列出来了,参考官方文档:https://docs.microsoft.com/zh-cn/aspnet/core/fundamentals/dependency-injection?view=aspnetcore-5.0
框架自带的一些符合Add{GROUP_NAME}约定的服务,如:AddControllers、AddDbContext、AddDefaultIdentity等,会自动注册该框架功能所需的所有服务。
1.服务生存周期
Tran.
前言假设我们有三个Service类实现了同一接口,示例代码如下:publicinterfaceIService{}
publicclassServiceA:IService{}
publicclassServiceB:IService{}
publicclassServiceC:IService{}我们希望在运行时使用依赖注入...
IoC:控制反转。在一个有层级的结构中,上层依赖下层,下层的改变会影响上层。控制反转就是将自上而下的依赖链部分反转。由A->B,转变为A->Interface<-B。从中间抽象出一层来,上下2层都依赖他。只要中间这一层不变,则2端可以自由发挥。
DI:依赖注入。虽然自己依赖某个类的运行,但是自己不主动去生成某个实例,而是由调用者去生成(将依赖由自己生成变成外部注入)。自己只需要...
在现代 Web 应用程序
中,调用第三方 Web API 来增强应用程序的功能是很常见的。有数以千计的免费和商业 API 可用,如果您知道如何在
ASP.NET Core 应用程序
中使用这些 API,您就可以构建非常强大的业务应用程序。在这篇文章
中,我将解释如何在
ASP.NET Core 应用程序
中使用第三方 Web API。
下载:Download Source Code
好的,我来给你简单介绍一下如何使用 ASP.NET Core 写一个文件下载接口,数据来自数据库。
首先,你需要在你的 ASP.NET Core 项目中引入相关的命名空间,例如:
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
然后,你需要准备好文件的信息,并将其存储在数据库中。这里假设你已经有了一个数据库上下文,名为 `DbContext`。
接着,你需要在你的控制器中创建一个新的接口来处理文件下载请求。这里假设你的控制器名为 `FileController`。
具体实现方式如下:
[Route("api/[controller]")]
[ApiController]
public class FileController : ControllerBase
private readonly DbContext _context;
public FileController(DbContext context)
_context = context;
[HttpGet("{id}")]
public async Task<IActionResult> Download(int id)
// 根据文件 ID 从数据库中查询文件信息
var file = await _context.Files.FirstOrDefaultAsync(f => f.Id == id);
if (file == null)
// 如果文件不存在,返回 404 错误
return NotFound();
// 读取文件数据
var fileBytes = System.IO.File.ReadAllBytes(file.FilePath);
// 返回文件数据
return File(fileBytes, file.ContentType, file.FileName);
上面的代码中,我们在 `Download` 方法中接收了文件 ID 作为参数,然后从数据库中查询文件信息。如