C#.NET SimpleInjector 详解

简介

Simple Injector 是一个专注于高性能、易用性和可测试性的 .NET 依赖注入(DI)容器,支持 .NET Framework、.NET Core、Xamarin 等多平台。

设计原则:简单、快速、可预测。它通过编译时及运行时验证帮助早发现配置错误,并力求将依赖解析的开销降到最低。

核心特性:

  • 高性能:使用表达式树和编译器优化,解析速度快,接近手动构造。

  • 严格诊断:内置诊断工具,检测配置错误(如 Captive Dependency)。

  • 简单 API:专注于构造函数注入,配置清晰,避免复杂绑定。

  • 跨平台支持:支持 .NET Framework、.NET Core.NET 5+

  • ASP.NET Core 集成:提供官方适配器,替换默认 DI 容器。

  • 扩展性:支持拦截器、装饰器和自定义生命周期。

  • 开源免费:MIT 许可,活跃社区维护。

优点:

  • 极高的解析性能,接近手写代码。

  • 强大的诊断功能,捕获配置错误。

  • API 简洁,专注于构造函数注入,鼓励最佳实践。

  • ASP.NET Core 集成良好,适合现代 .NET 项目。

缺点:

  • 不支持属性注入或方法注入,强制构造函数注入(可能限制某些场景)。

  • 学习曲线略陡,尤其在诊断和配置方面。

  • 功能较 Autofac 少,复杂绑定支持有限。

  • 配置需手动验证作用域,可能增加开发成本。

基础用法

安装与配置
dotnet add package SimpleInjector
基本服务注册
using SimpleInjector;

// 定义服务接口和实现
public interface ILogger {
    void Log(string message);
}

public class ConsoleLogger : ILogger {
    public void Log(string message) {
        Console.WriteLine($"[LOG] {message}");
    }
}

// 创建容器并注册服务
var container = new Container();
container.Register<ILogger, ConsoleLogger>(Lifestyle.Transient);

// 验证配置(可选但推荐)
container.Verify();

// 解析服务
var logger = container.GetInstance<ILogger>();
logger.Log("Hello from SimpleInjector!");
注册与解析服务
// 基础注册
container.Register<IUserRepository, SqlUserRepository>(Lifestyle.Transient);
container.Register<ILogger, FileLogger>(Lifestyle.Singleton);

// 解析实例
var userService = container.GetInstance<IUserService>();
模块化配置(IPackage)
// 定义模块
public class DataPackage : IPackage {
    public void RegisterServices(Container container) {
        container.Register<IDbContext, AppDbContext>(Lifestyle.Scoped);
    }
}

// 主入口点加载模块
container.RegisterPackages(AppDomain.CurrentDomain.GetAssemblies());

核心类型与 API

Container
  • Simple Injector 的核心容器类型,负责注册、验证和解析所有服务。
Lifestyle
  • 描述实例创建与缓存策略的枚举或类型:Transient, Singleton, Scoped(以及 AsyncScoped)等。
Scope / AsyncScopedLifestyle
  • 管理请求作用域(如 Web 请求)或异步操作作用域内的实例。

注册服务与生命周期

生命周期注册方式场景
TransientRegister<TService, TImpl>() (默认)无状态、轻量服务
SingletonRegister<TService, TImpl>(Lifestyle.Singleton)全局共享、线程安全
ScopedRegister<TService, TImpl>(Lifestyle.Scoped)Web 请求、工作单元(Unit of Work)
Async ScopedLifestyle.AsyncScoped + Register<…>异步流/后台任务作用域
var container = new Container();

// 默认即为 Transient
container.Register<IUserRepository, UserRepository>();

// Singleton(容器生命周期内唯一实例)
container.Register<IAppSettings, AppSettings>(Lifestyle.Singleton);

// Scoped(Scoped 需先调用 container.BeginLifetimeScope())
container.Register<IDbContext, MyDbContext>(Lifestyle.Scoped);

作用域管理

同步作用域
using (AsyncScopedLifestyle.BeginScope(container))
{
    var svc = container.GetInstance<IMyScopedService>();
    // 同一作用域内多次 GetInstance 返回同一实例
}
异步作用域
await AsyncScopedLifestyle.BeginScopeAsync(container);
// 在异步方法中使用 container.GetInstance<…>()
ASP.NET Core 集成
services.AddSimpleInjector(container, options =>
{
    options.AddAspNetCore()
           .AddControllerActivation();
});
// Startup.Configure:
app.UseSimpleInjector(container);
container.Verify();

高级用法

泛型和开放泛型
// IRepository<T> → Repository<T>
container.Register(typeof(IRepository<>), typeof(Repository<>), Lifestyle.Transient);
多实现注册
container.Collection.Register<IUserService>(typeof(UserService1), typeof(UserService2));

var services = container.GetAllInstances<IUserService>();
条件注册
container.RegisterConditional<IUserService, UserService>(
    c => c.Consumer.ImplementationType == typeof(UserController), Lifestyle.Scoped);
基于约定的批量注册
// 从程序集中批量注册服务
var assembly = typeof(Program).Assembly;
container.Register<IRepository, CustomerRepository>(Lifestyle.Scoped);
container.Register<IValidator, CustomerValidator>(Lifestyle.Scoped);

// 或使用约定批量注册
container.Register(typeof(IRepository<>), assembly);
container.Register(typeof(IValidator<>), assembly);

// 注册同一命名空间下所有实现
var types = container.GetTypesToRegister(
    typeof(IHandler<>), 
    new[] { typeof(OrderHandler).Assembly }
);

container.Collection.Register(typeof(IHandler<>), types);
带参数的注册
// 使用委托注册
container.Register<IMailService>(() => {
    var config = container.GetInstance<IConfiguration>();
    return new SmtpMailService(config.SmtpServer);
}, Lifestyle.Scoped);

// 注册已存在的实例
var settings = new AppSettings { ApiKey = "12345" };
container.RegisterInstance<IAppSettings>(settings);
委托工厂注册
container.Register(() =>
{
    var cfg = container.GetInstance<IConfiguration>();
    return new SqlConnection(cfg.GetConnectionString("Default"));
}, Lifestyle.Singleton);

container.Register<IPaymentService>(() => {
    var config = container.GetInstance<IConfiguration>();
    return new PaymentService(config.ApiKey);
}, Lifestyle.Singleton);
装饰器
// 基础实现
container.Register<IOrderService, OrderService>();

// 注册装饰器(执行顺序由下到上)
container.RegisterDecorator<IOrderService, OrderServiceLogDecorator>();
container.RegisterDecorator<IOrderService, OrderServiceCacheDecorator>();

// 解析时得到:CacheDecorator > LogDecorator > OrderService
拦截器与 AOP
// 使用委托拦截方法调用
container.Register<IService, ServiceImplementation>();
container.InterceptWith<LoggingInterceptor>(service => service is IService);

public class LoggingInterceptor : IInterceptor {
    private readonly ILogger _logger;

    public LoggingInterceptor(ILogger logger) {
        _logger = logger;
    }

    public object Intercept(Invocation invocation) {
        _logger.Log($"调用方法: {invocation.Method.Name}");
        var result = invocation.Proceed();
        _logger.Log($"方法返回: {result}");
        return result;
    }
}
异步支持

使用 AsyncScopedLifestyle 支持异步操作:

container.Options.DefaultScopedLifestyle = new AsyncScopedLifestyle();
using (AsyncScopedLifestyle.BeginScope(container))
{
    var service = container.GetInstance<IUserService>();
}
工厂模式

通过工厂动态创建实例:

container.Register<IUserServiceFactory, UserServiceFactory>();
public class UserServiceFactory
{
    private readonly Container _container;

    public UserServiceFactory(Container container)
    {
        _container = container;
    }

    public IUserService Create() => _container.GetInstance<IUserService>();
}
预编译注册:提升首次解析性能
container.Register<IFastService, FastService>(Lifestyle.Singleton);
container.Compile(); // 预编译注册
预编译容器(.NET 8+)
// 生成预编译表达式树
var expression = container.GetRegistration(typeof(IService)).BuildExpression();
var factory = Expression.Lambda<Func<IService>>(expression).Compile();

// 高频调用直接使用 factory()
var service = factory();
避免反射扫描
// 明确指定程序集(加速启动)
container.Collection.Register<IValidator>(
    typeof(UserValidator).Assembly.GetExportedTypes()
    .Where(t => t.Name.EndsWith("Validator")));
编译时验证
// 启动时检查问题(避免运行时错误)
container.Verify(VerificationOption.VerifyAndDiagnose);

// 输出诊断结果
var diagnostics = container.GetRegistrationDiagnostics();
File.WriteAllText("diag.txt", diagnostics);
分析工具
// 输出依赖图
var graph = container.GetRegistrationGraph();
File.WriteAllText("graph.dot", graph.ToDot());

// 转化为可视化图表
// dot -Tpng graph.dot -o graph.png

集成 ASP.NET / ASP.NET Core

ASP.NET MVC / Web API
var container = new Container();
container.Options.DefaultScopedLifestyle = new WebRequestLifestyle();

container.RegisterMvcControllers(Assembly.GetExecutingAssembly());
container.Verify();

DependencyResolver.SetResolver(new SimpleInjectorDependencyResolver(container));
ASP.NET Core
// Program.cs
var builder = WebApplication.CreateBuilder(args);
var container = new Container();
container.Options.DefaultScopedLifestyle = new AsyncScopedLifestyle();

builder.Services.AddSimpleInjector(container, options =>
{
    options.AddAspNetCore()
           .AddControllerActivation()
           .AddViewComponentActivation();
});

var app = builder.Build();
app.UseSimpleInjector(container);
container.Verify();

生命周期管理与验证

生命周期验证
// 验证容器配置
try {
    container.Verify();
} catch (ValidationException ex) {
    Console.WriteLine("容器配置错误: " + ex.Message);
}
处理作用域
// 在控制台应用中手动管理作用域
using (var scope = container.BeginExecutionContextScope()) {
    var service = container.GetInstance<IScopedService>();
    service.Process();
} // 作用域结束时释放资源
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值