依赖注入集成

July 19, 2026 · View on GitHub

AspectCore 在提供 AOP 的同时,内置了一个轻量、高性能、可与动态代理无缝集成的 IoC 容器。你既可以直接使用这个内置容器 IServiceContext,也可以让它接管 Microsoft.Extensions.DependencyInjection,在 ASP.NET Core 中替换默认容器。本页覆盖两种用法:注册、解析、生命周期、构造器与属性注入、AOP 集成,以及一段与 Autofac 的性能对比。

内置容器 IServiceContext

内置容器的接口是 IServiceContext(命名空间 AspectCore.DependencyInjection),默认实现为 ServiceContext。它随 AspectCore.Core 提供。

服务注册

IServiceContext 通过扩展方法提供类型、实例、委托三种注册方式:

using AspectCore.DependencyInjection;

IServiceContext services = new ServiceContext();

// 按类型注册
services.AddType<ILogger, Logger>();

// 按实例注册(生命周期为单例)
services.AddInstance<ITaskService>(new TaskService());

// 按委托工厂注册(委托入参是 IServiceResolver)
services.AddDelegate<ITaskService, TaskService>(resolver => new TaskService());

AddType / AddDelegate 都带可选的 Lifetime 参数(默认 Transient);AddInstance 注册的服务固定是单例。

服务解析

先用 Build()IServiceContext 构建成 IServiceResolver,再解析服务:

// 构建解析器
IServiceResolver resolver = services.Build();

// 解析单个服务
ISampleService sampleService = resolver.Resolve<ISampleService>();

// 解析单个服务,未注册时抛异常
ISampleService required = resolver.ResolveRequired<ISampleService>();

// 解析服务集合,未注册时返回空集合
IEnumerable<ISampleService> many = resolver.ResolveMany<ISampleService>();

生命周期

Lifetime 枚举提供三种生命周期:

  • 瞬时(Transient):每次请求都创建新实例,适合轻量、无状态的服务。
  • 作用域(Scoped):每个作用域内创建一次。
  • 单例(Singleton):首次解析时创建,之后所有解析复用同一实例。
services.AddType<ILogger, Logger>(Lifetime.Singleton);
services.AddType<ITaskService, TaskService>(Lifetime.Scoped);
services.AddType<ISampleService, SampleService>(Lifetime.Transient);

构造器注入与属性注入

内置容器支持构造器注入和属性注入两种方式:

using AspectCore.DependencyInjection;

public class SampleService : ISampleService
{
    private readonly ISampleRepository _repository;
    private readonly ILogger _logger;

    // 构造器注入
    public SampleService(ISampleRepository repository, ILogger logger)
    {
        _repository = repository;
        _logger = logger;
    }
}

public class SampleRepository : ISampleRepository
{
    // 属性注入:标记 [FromServiceContext] 且允许 set 的属性会被自动注入
    [FromServiceContext]
    public ILogger Logger { get; set; }
}

属性注入的条件是:属性标记 [FromServiceContext](命名空间 AspectCore.DependencyInjection)且可写。

AOP 集成

内置容器默认开启与 DynamicProxy 的 AOP 集成,通过 Configure 方法配置拦截器——用的是与其他宿主一致的 IAspectConfiguration

services.Configure(config =>
{
    config.Interceptors.AddTyped<SampleInterceptorAttribute>();
});

因此从容器解析出来的实例,如果命中了拦截器配置,就已经是织入切面的代理。拦截器配置的完整说明见拦截器配置

与 Microsoft.Extensions.DependencyInjection 集成

多数应用不会直接用 ServiceContext,而是让 AspectCore 接管 IServiceCollection。安装 AspectCore.Extensions.DependencyInjection

dotnet add package AspectCore.Extensions.DependencyInjection

配置拦截器:ConfigureDynamicProxy

IServiceCollection 上调用一次 ConfigureDynamicProxy(...) 启用动态代理并注册全局拦截器:

using AspectCore.Extensions.DependencyInjection;

services.AddTransient<ICustomService, CustomService>();
services.ConfigureDynamicProxy(config =>
{
    config.Interceptors.AddTyped<CustomInterceptorAttribute>();
});

构建容器的两种方式

方式一:DynamicProxyServiceProviderFactory(ASP.NET Core / 泛型主机推荐)

在主机层用 IServiceProviderFactory 接管容器构建,业务代码无感:

using AspectCore.Extensions.DependencyInjection;

Host.CreateDefaultBuilder(args)
    .UseServiceProviderFactory(new DynamicProxyServiceProviderFactory())
    .ConfigureWebHostDefaults(webBuilder => webBuilder.UseStartup<Startup>());

方式二:BuildDynamicProxyProvider / BuildServiceContextProvider(手动构建)

控制台或测试场景下直接构建 IServiceProvider

// 直接得到已启用动态代理的 ServiceProvider
var provider = services.BuildDynamicProxyProvider();

// 或者把 IServiceCollection 桥接到内置 ServiceContext 再构建
var provider2 = services.BuildServiceContextProvider();

在 ASP.NET Core 中使用

Program/Startup 中挂上 DynamicProxyServiceProviderFactory,并在 ConfigureServices 里照常注册服务、调用一次 ConfigureDynamicProxy(),即可用 AspectCore 的容器替换默认 DI。完整流程见快速上手

性能

内置容器在设计上追求低开销。官方以 Autofac(4.6.2)为对比,从解析简单对象、属性注入、构造器注入三方面做基准测试。以下数据来自历史基准(.NET Core 2.0,BenchmarkDotNet v0.10.8),仅供了解量级,实际数字随运行环境而变:

MethodMeanAllocated
Autofac_Sample_Resolve494.83 ns752 B
AspectCore_Sample_Resolve88.52 ns88 B
Autofac_PropertyInjection2,014.46 ns1856 B
AspectCore_PropertyInjection307.55 ns336 B
Autofac_ConstructorInjection1,465.71 ns1920 B
AspectCore_ConstructorInjection284.94 ns312 B

这组数据是历史环境下的旧基准,用于说明内置容器相对轻量,不代表当前版本或你的运行环境的确切表现。需要最新数据请在自己的环境重跑基准。

下一步