You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET依赖注入:如何避免在服务类中使用new实例化对象

在.NET 8 Blazor Server中通过依赖注入创建带参数的对象并注入ILogger

核心思路

避免直接使用new的关键是利用DI容器的服务提供能力,结合ActivatorUtilities自动注入框架管理的依赖(比如ILogger),同时传递自定义业务参数。

步骤1:定义MyUserClass(构造函数包含依赖与自定义参数)

首先确保MyUserClass的构造函数同时接收需要注入的ILogger和自定义参数:

public class MyUserClass
{
    private readonly ILogger<MyUserClass> _logger;
    public string UserId { get; }

    // DI自动注入ILogger,自定义参数由调用时传入
    public MyUserClass(ILogger<MyUserClass> logger, string userId)
    {
        _logger = logger;
        UserId = userId;
    }

    public void ExecuteUserLogic()
    {
        _logger.LogInformation($"执行用户 {UserId} 的业务逻辑");
    }
}

方法1:通过IServiceProvider直接创建实例(最直接)

在MyService中注入IServiceProvider,使用ActivatorUtilities.CreateInstance方法创建MyUserClass——该方法会自动从DI容器中解析ILogger,同时传入你的自定义参数:

public class MyService : IMyService
{
    private readonly IServiceProvider _serviceProvider;

    // 注入IServiceProvider
    public MyService(IServiceProvider serviceProvider)
    {
        _serviceProvider = serviceProvider;
    }

    public void BatchProcessUsers(List<string> userIds)
    {
        foreach (var userId in userIds)
        {
            // 创建实例:自动注入ILogger,传入userId参数
            var userInstance = ActivatorUtilities.CreateInstance<MyUserClass>(_serviceProvider, userId);
            userInstance.ExecuteUserLogic();
        }
    }
}

方法2:注册工厂委托(适合复杂创建逻辑)

如果MyUserClass的创建逻辑复杂,或者需要集中管理创建规则,可以注册一个工厂委托:

1. 在Program.cs中注册工厂

var builder = WebApplication.CreateBuilder(args);

// 注册MyUserClass的工厂:接收userId参数,返回实例
builder.Services.AddTransient<Func<string, MyUserClass>>(sp =>
{
    return userId => ActivatorUtilities.CreateInstance<MyUserClass>(sp, userId);
});

// 注册你的MyService
builder.Services.AddScoped<IMyService, MyService>();

2. 在MyService中注入工厂并使用

public class MyService : IMyService
{
    private readonly Func<string, MyUserClass> _userFactory;

    // 注入工厂委托
    public MyService(Func<string, MyUserClass> userFactory)
    {
        _userFactory = userFactory;
    }

    public void BatchProcessUsers(List<string> userIds)
    {
        foreach (var userId in userIds)
        {
            // 直接调用工厂创建实例
            var userInstance = _userFactory(userId);
            userInstance.ExecuteUserLogic();
        }
    }
}

关键注意事项

  • ILogger自动注册:.NET Core默认已注册ILogger<T>,无需额外配置即可自动注入。
  • 生命周期匹配:如果MyService是Singleton,不要让MyUserClass依赖Scoped服务(比如HttpContextAccessor),否则会导致生命周期不匹配错误。若必须依赖,需使用IServiceScopeFactory创建独立作用域。
  • 无需注册MyUserClass到DI:通过ActivatorUtilities创建实例时,只要它的依赖(如ILogger)已在DI中注册即可,无需单独注册MyUserClass。

内容的提问来源于stack exchange,提问作者MagicJP

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 21:23:24