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

ASP.NET Core项目中Dependency Injection突然失效问题求助

ASP.NET Core 依赖注入失效问题排查

我在ASP.NET Core项目中搭建重定向管理代码,POC阶段的重定向/DI代码原本正常运行,但开发完数据库相关部分后,Dependency Injection突然失效了。以下是简化后的代码示例及输出结果,求分析问题原因!


主项目Startup.cs

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        Console.WriteLine("xxxx about to services.AddRedirections()");
        services.AddRedirections();
        Console.WriteLine("xxxx done services.AddRedirections()");
    }

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        ConfigureRewriteMiddleware(app, requestLocalizationOptions);
    }

    private void ConfigureRewriteMiddleware(IApplicationBuilder app, RequestLocalizationOptions requestLocalizationOptions)
    {
        app.UseCustomRedirectsRewriter();
    }
}

重定向项目ServiceCollectionExtensions.cs

public static class ServiceCollectionExtensions
{
    public static void AddRedirections(this IServiceCollection serviceCollection)
    {
        Console.WriteLine("xxxx AddRedirections");
        serviceCollection.AddSingleton<IRedirectsService, RedirectsService>();
    }
}

主项目CustomRedirectsRewriter.cs

public static class CustomRedirectsRewriter
{
    public static void UseCustomRedirectsRewriter(this IApplicationBuilder app)
    {
        var customRedirects = new CustomRedirects();
        var customRedirectsOptions = new RewriteOptions().Add(customRedirects.ProcessRedirects);
        app.UseRewriter(customRedirectsOptions);
    }
}

主项目CustomRedirects.cs

public class CustomRedirects
{
    private IRedirectsService _redirectsService;

    public CustomRedirects()
    {
        Console.WriteLine("xxxx CustomRedirects()");
        var services = new ServiceCollection();
        var serviceProvider = services.BuildServiceProvider();

        try
        {
            _redirectsService = serviceProvider.GetRequiredService<IRedirectsService>();
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message + " xxxxxx " + ex.StackTrace);
        }

        if (_redirectsService == null) Console.WriteLine("xxxx redirectsService is null in CustomRedirects()");
    }

    public async void ProcessCustomRedirects(RewriteContext rewriteContext)
    {
        if (_redirectsService == null)
        {
            //I added additional attempts to reinitialize service later in code
            Console.WriteLine("xxxx redirectsService is null in ProcessCustomRedirects() and wasn't initalized in constructor");
            try
            {
                var services = new ServiceCollection();
                var serviceProvider = services.BuildServiceProvider();
                _redirectsService = serviceProvider.GetRequiredService<IRedirectsService>();
            }
            catch (Exception ex)
            {
                Console.WriteLine("xxxx redirectsService is still null in ProcessCustomRedirects() after second attempt");
            }
        }

        if (_redirectsService != null)
        {
            //do redirects
        }
    }
}

重定向项目RedirectsService.cs

public class RedirectsService : IRedirectsService
{
    public RedirectsService() {}

    public async Task<List<RedirectModel>> GetRedirectsForDomain(string domain)
    {
        var redirectsList = new List<RedirectModel>();
        return redirectsList;
    }
}

重定向项目IRedirectsService.cs

public interface IRedirectsService
{
    Task<List<RedirectModel>> GetRedirectsForDomain(string domains);
}

输出结果

xxxx about to services.AddRedirections()
xxxx AddRedirections
xxxx done services.AddRedirections()
xxxx CustomRedirects()

No service for type 'IRedirectsService' has been registered. xxxxxx at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider provider, Type serviceType)

xxxx redirectsService is null in CustomRedirects()
xxxx redirectsService is null in ProcessCustomRedirects() and wasn't initalized in constructor
xxxx redirectsService is still null in ProcessCustomRedirects() after second attempt

问题根源与修复方案

问题核心

你在CustomRedirects的构造函数和ProcessCustomRedirects方法里,手动创建了全新的ServiceCollection和ServiceProvider实例,这个新容器和Startup中注册服务的全局容器完全独立,自然找不到已注册的IRedirectsService。

修复步骤

  1. 让CustomRedirects通过构造函数注入依赖
    修改CustomRedirects,移除手动创建容器的逻辑,直接通过构造函数接收IRedirectsService:

    public class CustomRedirects
    {
        private readonly IRedirectsService _redirectsService;
    
        // 构造函数注入依赖
        public CustomRedirects(IRedirectsService redirectsService)
        {
            Console.WriteLine("xxxx CustomRedirects()");
            _redirectsService = redirectsService ?? throw new ArgumentNullException(nameof(redirectsService));
        }
    
        // 把async void改为async Task,避免异步异常丢失
        public async Task ProcessCustomRedirects(RewriteContext rewriteContext)
        {
            // 直接使用注入的服务执行逻辑
            var redirects = await _redirectsService.GetRedirectsForDomain("your-target-domain");
            // 实现重定向逻辑...
        }
    }
    
  2. 从全局DI容器获取CustomRedirects实例
    修改CustomRedirectsRewriter,不再手动new CustomRedirects(),而是从应用的服务容器中获取:

    public static class CustomRedirectsRewriter
    {
        public static void UseCustomRedirectsRewriter(this IApplicationBuilder app)
        {
            // 从全局DI容器获取已注入依赖的CustomRedirects实例
            var customRedirects = app.ApplicationServices.GetRequiredService<CustomRedirects>();
            var customRedirectsOptions = new RewriteOptions().Add(customRedirects.ProcessCustomRedirects);
            app.UseRewriter(customRedirectsOptions);
        }
    }
    
  3. 注册CustomRedirects到DI容器
    在AddRedirections扩展方法中添加CustomRedirects的注册,让DI容器能解析它的依赖:

    public static class ServiceCollectionExtensions
    {
        public static void AddRedirections(this IServiceCollection serviceCollection)
        {
            Console.WriteLine("xxxx AddRedirections");
            serviceCollection.AddSingleton<IRedirectsService, RedirectsService>();
            // 注册CustomRedirects为单例
            serviceCollection.AddSingleton<CustomRedirects>();
        }
    }
    

额外提示

  • 永远不要在业务代码中手动创建ServiceCollection/ServiceProvider,全局容器由ASP.NET Core框架管理,通过IApplicationBuilder.ApplicationServices或构造函数注入获取服务。
  • 避免使用async void,异步方法应返回async Task,否则会导致未捕获的异常和线程泄漏问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 14:20:34