Fast.DependencyInjection
版本 3.5.29;目标 net8.0、net9.0、net10.0;依赖 Fast.Runtime。按生命周期标记接口注册框架已发现的类型。
bash
dotnet add package Fast.DependencyInjection注册与生命周期
Fast.DependencyInjection.IServiceCollectionExtension.AddDependencyInjection(this IServiceCollection services) 无额外选项,返回原服务集合。
| 标记接口 | 注册生命周期 |
|---|---|
ITransientDependency | Transient |
IScopedDependency | Scoped |
ISingletonDependency | Singleton |
IDependency | 公共基标记,不能单独代替具体生命周期接口 |
以下为消费端 Program.cs,使用 Microsoft.NET.Sdk.Web,目标选择本页列出的 .NET 8、9 或 10,并安装上方指定包。app.Run() 表示正常宿主启动;本次文档维护不会执行它。
csharp
using Fast.DependencyInjection;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.AspNetCore.Builder;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddDependencyInjection();
var app = builder.Build();
app.MapGet("/message", (IMessageFormatter formatter) => formatter.Format("hello"));
app.Run();
public interface IMessageFormatter
{
string Format(string value);
}
public sealed class MessageFormatter : IMessageFormatter, IScopedDependency
{
public string Format(string value) => $"[{value}]";
}该类必须处在 MAppContext.EffectiveTypes 的发现范围内。方法筛选实现 IDependency 的非抽象类,忽略生命周期标记、IDisposable、IAsyncDisposable 等接口,并按符合程序集与泛型约束的业务接口注册。有业务接口时不自动同时注册具体类;没有可注册业务接口时按具体类型注册。
解析与扩展边界
- 一个实现可以注册多个业务接口,但多个接口的独立 ServiceDescriptor 不构成“跨接口必然同一实例”的承诺。
- 每个类应选择一个生命周期标记。实现多个标记时源码从接口枚举中选择最后一个,不应依赖枚举顺序表达优先级。
- 框架还注册
Func<string, TDependency, object>命名解析委托,名字来自类型简单名,通过实际业务接口定位实现。同名类型在注册时明确拒绝。 - Singleton 实现不可直接持有请求 Scoped 服务。扫描注册没有替代应用对生命周期、资源释放的设计。
- 开放泛型按现有泛型参数数量筛选,不代表任意复杂泛型映射均受支持。
来源与验证
依据 注册和命名解析实现。示例为静态核对片段,本轮未编译或构造服务容器。
命名解析与生命周期
名称映射限定在当前 IServiceCollection,不跨宿主共享。命名解析通过实际注册的主业务接口定位实现,与该接口的 Singleton/Scoped 解析共享实例,不重复接管对象释放。多个不同业务接口的既有独立描述符仍不保证共用一个实例。
同名实现和多个生命周期标记会在注册时明确失败。闭合泛型保留具体参数;开放泛型的字符串命名解析必须改为明确的闭合接口解析。抽象类和接口不是可实例化实现。
