在 .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)
);
}
}

注册特性(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
如果你还在为一堆 AddScoped
、AddTransient
头疼,Injectio 会是你的救星!