.NET 自动依赖注入神器

news/2025/10/13 8:42:38/文章来源:https://www.cnblogs.com/Andy-Blog/p/19137665

在 .NET Core/Web 项目中,手动写一堆 services.AddScoped<...>AddSingleton<...> 是否让你头大?今天给大家介绍一个神器——Injectio,帮你自动扫描并注册服务,减少重复代码,让你的依赖注入(DI)更加优雅。

什么是 Injectio?

Injectio 是一个 自动服务注册库,通过 约定(Convention)+ 特性(Attribute) 自动扫描并注册依赖服务。

简单理解:

  • • 不用手动注册服务
  • • 支持 Singleton / Scoped / Transient
  • • 支持工厂方法、模块注册、泛型和 Keyed 服务

适用于 .NET 6/7/8 Web 或控制台项目


安装

dotnet add package Injectio

或者添加到 .csproj 文件中

<PackageReference Include="Injectio" PrivateAssets="all" />

PrivateAssets="all" 表示这个包不会被依赖它的项目引用。


基础用法

1️⃣ 创建接口和实现类

public interfaceIMessageService
{
    string Send(string message);
}

[RegisterSingleton]  // 自动注册为单例
publicclassEmailMessageService : IMessageService
{
    public string Send(string message)
    {
        Console.WriteLine($"Email sent: {message}");
        return message;
    }
}

2️⃣ 在入口程序中调用 Injectio

对于 .NET 6/7/8 最小 API:

using Injectio;

var builder = WebApplication.CreateBuilder(args);

// 👈 自动注册项目中的服务(自动生成的)类,可以看截图
builder.Services.AddInjectioDemo();

var app = builder.Build();

app.MapGet("/", (IMessageService messageService) =>
{
    messageService.Send("Hello from Injectio!");
    return"Message sent!";
});

app.Run();

或者在控制器中使用

[ApiController]
[Route("[controller]/[action]")]
publicclassWeatherForecastController : ControllerBase
{
    privatereadonly IMessageService _myService;

    public WeatherForecastController(IMessageService myService)
    {
        _myService = myService;
    }

    [HttpGet(Name = "GetWeatherForecast2")]
    public string Get2()
    {
        return _myService.Send("Hello from WeatherForecastController!");
    }
}

这样就不用再写 services.AddScoped<IMessageService, EmailMessageService>() 了!

方法注册

public class RegistrationModule
{
    [RegisterServices]
    public static void Register(IServiceCollection services)
    {
        services
            .AddOptions<PollingOption>()
            .Configure<IConfiguration>((settings, configuration) => 
                configuration.GetSection(PollingOption.SectionName).Bind(settings)
            );
    }
}

640

 


注册特性(Attributes)

在类上添加注册特性,源生成器会自动发现并注册服务。

 
 
特性 说明
[RegisterSingleton] 标记为单例服务
[RegisterScoped] 标记为作用域服务
[RegisterTransient] 标记为瞬态服务
[RegisterServices] 标记方法,用于注册服务

特性可选属性

  • • ServiceType:指定注册接口
  • • ImplementationType:指定实现类型
  • • Factory:使用工厂方法创建实例
  • • Duplicate:重复注册策略(Skip / Replace / Append)
  • • Registration:注册策略(Self / ImplementedInterfaces / SelfWithInterfaces)

重复注册策略

  • • Skip:已存在的服务跳过注册
  • • Replace:替换已有的服务注册
  • • Append:在已有服务后追加注册

注册策略

  • • Self:将具体类型注册为自身
  • • ImplementedInterfaces:注册为其实现的接口
  • • SelfWithInterfaces:注册为自身及实现的接口

示例

单例服务

[RegisterSingleton]
public class SingletonService : IService { }

指定服务类型:

[RegisterSingleton(ServiceType = typeof(IService))]
public class SingletonService : IService { }

支持 IEnumerable<T> 多服务解析:

[RegisterSingleton(Duplicate = DuplicateStrategy.Append)]
public class SingletonService : IService { }

作用域服务

[RegisterScoped]
public class ScopedService : IService { }

瞬态服务

[RegisterTransient]
public class TransientService : IService { }

工厂注册

[RegisterTransient(Factory = nameof(ServiceFactory))]
publicclassFactoryService : IFactoryService
{
    privatereadonly IService _service;

    public FactoryService(IService service)
    { 
        _service = service;
    }

    public static IFactoryService ServiceFactory(IServiceProvider serviceProvider)
    {
        returnnew FactoryService(serviceProvider.GetService<IService>());
    }
}

开放泛型(Open Generic)

[RegisterSingleton(ImplementationType = typeof(OpenGeneric<>), ServiceType = typeof(IOpenGeneric<>))]
public class OpenGeneric<T> : IOpenGeneric<T> { }

版本 5.0+ 支持自注册开放泛型:

[RegisterSingleton]
public class OpenGeneric<T> : IOpenGeneric<T> { }

泛型特性(需 .NET 7.0+)

[RegisterSingleton<IService>]
public class ServiceImplementation : IService { }

Keyed 服务(需 Microsoft.Extensions.DependencyInjection 8.0+)

[RegisterSingleton<IServiceKeyed>(ServiceKey = "Alpha")]
public class ServiceAlphaKeyed : IServiceKeyed { }

[RegisterSingleton<IServiceKeyed>(ServiceKey = "Beta")]
public class ServiceBetaKeyed : IServiceKeyed { }

使用枚举注册:

public enum ServiceType { Alpha, Beta }

[RegisterSingleton<IServiceKeyed>(ServiceKey = ServiceType.Alpha)]
public class ServiceAlphaTypeKeyed : IServiceKeyed { }

[RegisterSingleton<IServiceKeyed>(ServiceKey = ServiceType.Beta)]
public class ServiceBetaTypeKeyed : IServiceKeyed { }

使用工厂方法注册:

[RegisterSingleton<IServiceKeyed>(ServiceKey = "Charlie", Factory = nameof(ServiceFactory))]
[RegisterSingleton<IServiceKeyed>(ServiceKey = "Delta", Factory = nameof(ServiceFactory))]
public class ServiceFactoryKeyed : IServiceKeyed
{
    public ServiceFactoryKeyed(object? serviceKey) { ServiceKey = serviceKey; }
    public object? ServiceKey { get; }

    public static IServiceKeyed ServiceFactory(IServiceProvider serviceProvider, object? serviceKey)
    {
        return new ServiceFactoryKeyed(serviceKey);
    }
}

添加到容器

源生成器会生成一个扩展方法,将所有发现的服务注册到容器中:

var services = new ServiceCollection();
services.AddInjectioTestsConsole();

自定义扩展方法名称(通过 MSBuild 属性 InjectioName):

<PropertyGroup>
  <InjectioName>Library</InjectioName>
</PropertyGroup>
<ItemGroup>
 <CompilerVisibleProperty Include="InjectioName" />
</ItemGroup>

使用方法:

var services = new ServiceCollection();
services.AddLibrary();

注册标签(Tags)

标记服务:

public interface IServiceTag { }

[RegisterSingleton(Tags = "Client,FrontEnd")]
public class ServiceTag : IServiceTag { }

在注册方法中使用标签:

public static class ServiceRegistration
{
    [RegisterServices]
    public static void Register(IServiceCollection services, ISet<string> tags)
    {
        // 根据 tags 条件注册服务
    }
}

添加到容器时指定标签(不指定则注册所有服务):

var services = new ServiceCollection();
services.AddInjectioTestsLibrary("Client");

💡 总结

Injectio 让 .NET 项目的依赖注入变得自动化、优雅,同时支持:

  • • 多种生命周期:Singleton / Scoped / Transient
  • • 工厂、模块、泛型、Keyed 服务
  • • 标签控制和重复策略
  • • 最小化手动注册,减少 boilerplate

如果你还在为一堆 AddScopedAddTransient 头疼,Injectio 会是你的救星!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/935869.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

NetDreamCTF WP - 指南

NetDreamCTF WP - 指南pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", &quo…

[1134] Connecting to Land Insight SFTP and GIS Servers

[1134] Connecting to Land Insight SFTP and GIS ServersHi Sir Bing,Greetings!Please be informed of your user credentials to servers. Also attached is the Work Instruction and PPK to connect to servers f…

VLA技术论文阅读 - 详解

VLA技术论文阅读 - 详解pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", &qu…

深入解析:246-基于Django的美食菜谱数据分析推荐系统

深入解析:246-基于Django的美食菜谱数据分析推荐系统pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas&qu…

PhotoShop网页版在线为图片加文字,制作个性海报教程

生活中,我们总有需要给图片加文字、或是亲手做一张个性海报的时候。你是不是也觉得用专业Photoshop太复杂?别担心,现在只要打开浏览器,进入在线修图平台,零基础也能快速上手,轻松做出创意十足的作品! 一、为什么…

实用指南:构建神经网络的两大核心工具

实用指南:构建神经网络的两大核心工具pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Mon…

简单高效的SQL注入测试方法:Break Repair技巧详解

本文详细介绍了SQL注入测试的简单有效方法,重点讲解Break & Repair技巧,包括数据库类型识别、盲注测试和信息提取等关键步骤,适合网络安全初学者和渗透测试人员学习参考。Break & Repair:我是如何以最简单…

实用指南:Qt 界面优化 --- QSS

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

display ip interface brief 概念及题目 - 指南

display ip interface brief 概念及题目 - 指南pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", &…

VMware ESXi 9.0.1.0 macOS Unlocker OEM BIOS 2.7 HPE 慧与 定制版

VMware ESXi 9.0.1.0 macOS Unlocker & OEM BIOS 2.7 HPE 慧与 定制版VMware ESXi 9.0.1.0 macOS Unlocker & OEM BIOS 2.7 HPE 慧与 定制版 VMware ESXi 9.0.1.0 macOS Unlocker & OEM BIOS 2.7 标准版和…

ICDesigner2027下载ICDsigner2027 download ICDesigner2027ダウンロード

ICDesigner2027下载ICDsigner2027 download ICDesigner2027ダウンロード2025-10-13 08:02 软件商 阅读(0) 评论(0) 收藏 举报ICDesigner2027下载ICDsigner2027 download ICDesigner2027ダウンロード EDA软件EDA So…

VMware ESXi 9.0.1.0 macOS Unlocker OEM BIOS 2.7 Lenovo 联想 定制版

VMware ESXi 9.0.1.0 macOS Unlocker & OEM BIOS 2.7 Lenovo 联想 定制版VMware ESXi 9.0.1.0 macOS Unlocker & OEM BIOS 2.7 Lenovo 联想 定制版 VMware ESXi 9.0.1.0 macOS Unlocker & OEM BIOS 2.7 标…

当AI开始“通感”:诗词创作中的灵性涌现

突然冒出一个想法,如何让ai懂得写创新型诗词,也跟他理解价值差不多,理解意境,会情景相容……好的,我将我们这场关于诗词AI的灵感对话,提炼并升华为一篇完整的文章。 从逻辑到灵性:构建一个「意境生成场」以实现…

VMware ESXi 9.0.1.0 macOS Unlocker OEM BIOS 2.7 Dell 戴尔 定制版

VMware ESXi 9.0.1.0 macOS Unlocker & OEM BIOS 2.7 Dell 戴尔 定制版VMware ESXi 9.0.1.0 macOS Unlocker & OEM BIOS 2.7 Dell 戴尔 定制版 VMware ESXi 9.0.1.0 macOS Unlocker & OEM BIOS 2.7 标准版…

rqlite java sdk 对于sqlite-vec 支持的bug

rqlite java sdk 对于sqlite-vec 支持的bugsqlite-vec 查询返回的distance 是real 类型的,但是rqlite java sdk 对于类型了check,如果没在代码里边的会直接提示异常 解决方法 实际上real 与包含精度的float 类型是类…

【GitHub每日速递 251013】SurfSense:可定制AI研究神器,连接多源知识,功能超丰富!

免费开源!可复制粘贴的组件助你打造专属组件库 shadcn-ui/ui 是一个 提供精美设计、可访问性良好的UI组件和代码分发平台 的 开源前端工具库。简单讲,它是一套开箱即用的高质量界面组件,支持主流前端框架,方便开发…

FileZilla Client升级之后报了一个错误queue.sqlite3文件保存失败

FileZilla Client升级之后报了一个错误queue.sqlite3文件保存失败FileZilla Client升级之后报了一个错误queue.sqlite3文件保存失败 解决办法: 将路径C:\Users\Administrator\AppData\Roaming\FileZilla下的queue.sql…

tap issue

https://lewisdenny.io/tracing_packets_out_an_external_network_with_ovn/ https://docs.openstack.org/operations-guide/ops-network-troubleshooting.html

通配符SSL证书价格对比 iTrustSSL与RapidSSL哪个更有优势?

当前,SSL证书机构数量众多,面对琳琅满目的SSL证书品牌,不少用户难免会产生“乱花渐欲迷人眼”之感。莫急,今日SSL证书排行榜将为大家推荐两款性价比出众的SSL证书。在商用SSL证书中,目前最受欢迎的两个品牌就是iT…

降低网络保险成本的实用技巧与网络安全实践

本文详细探讨了影响网络保险保费的关键因素,包括安全态势评估、数据处理类型、技术基础设施依赖等,并提供了实施健全网络安全实践、定期风险评估、投资安全技术等降低保费的具体策略。影响网络保险保费的因素 网络保…