中间件DI错误

Ben*_*ger 0 c# dependency-injection asp.net-core

我试图实施重点验证在此提到的API .我遇到了一个问题,我在中间件类中使用注入的服务进行验证返回:

InvalidOperationException:无法从根提供程序解析'FoosballKeepr.Services.Interfaces.ILeagueService',因为它需要作用域服务'FoosballKeepr.Data.FoosballKeeprContext'.

我相信我正在Startup.cs中正确注册我的dbContext,服务和存储库.

public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    {
        //MVC
        services.AddMvc();

        //Database
        var connection = @"Server=localhost\SQLEXPRESS;Database=FoosballKeepr;Trusted_Connection=True;";
        services.AddDbContext<FoosballKeeprContext>(options => options.UseSqlServer(connection));

        //Services
        services.AddTransient<IPlayerService, PlayerService>();
        services.AddTransient<ILeagueService, LeagueService>();

        //Repositories
        services.AddTransient<IPlayerRepository, PlayerRepository>();
        services.AddTransient<ILeagueRepository, LeagueRepository>();
    }

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }

        app.UseMiddleware<ApiKeyValidatorMiddleware>();

        app.UseMvc();
    }
}
Run Code Online (Sandbox Code Playgroud)

自定义中间件验证器:

public class ApiKeyValidatorMiddleware
{
    private readonly RequestDelegate _next;
    private ILeagueService _leagueService;

    public ApiKeyValidatorMiddleware(RequestDelegate next, ILeagueService leagueService)
    {
        _next = next;
        _leagueService = leagueService;
    }

    public async Task Invoke(HttpContext context)
    {
        if (!context.Request.Headers.Keys.Contains("x-api-key"))
        {
            context.Response.StatusCode = 400;              
            await context.Response.WriteAsync("API Key Missing.");
            return;
        }
        else
        {
            int leagueId = _leagueService.ValidateApiKey(context.Request.Headers["x-api-key"]);

            if (leagueId == 0)
            {
                context.Response.StatusCode = 401;
                await context.Response.WriteAsync("Invalid API Key");
                return;
            }
            else
            {
                context.Items["LeagueId"] = leagueId;
            }
        }

        await _next.Invoke(context);
    }
}
Run Code Online (Sandbox Code Playgroud)

服务

    public class LeagueService : ILeagueService
{
    private readonly ILeagueRepository _leagueRepository;

    public LeagueService(ILeagueRepository leagueRepository)
    {
        _leagueRepository = leagueRepository;
    }

    public int ValidateApiKey(string apiKey)
    {
        return _leagueRepository.ValidateApiKey(apiKey);
    }
}
Run Code Online (Sandbox Code Playgroud)

知识库

public class LeagueRepository : ILeagueRepository
{
    private readonly FoosballKeeprContext _context;

    public LeagueRepository(FoosballKeeprContext context)
    {
        _context = context;
    }

    public int ValidateApiKey(string apiKey)
    {
        var query = from l in _context.League
                    where l.ApiKey == apiKey
                    select l.LeagueId;

        return query.FirstOrDefault();
    }
}
Run Code Online (Sandbox Code Playgroud)

这是我第一次实现自定义中间件功能,所以我觉得我的问题没有在正确的上下文中正确设置,但没有任何东西突然出现.这对任何人来说都很熟悉吗?

SO *_*ood 5

问题是中间件没有范围,因为:

每个应用程序生命周期构建一次中间件

因此,当您需要注入作用域服务时,您可以在Invoke操作中执行此操作(即所谓的方法注入):

public async Task Invoke(HttpContext context, ILeagueService service)
{
    //...
}
Run Code Online (Sandbox Code Playgroud)