首页 \ 问答 \ 没有注册类型服务(No service for type has been registered)

没有注册类型服务(No service for type has been registered)

我正在尝试实现ASP.NET Core中间件,这是我在项目中的完整代码:

public class HostMiddleware : IMiddleware
{
    public int Count { get; set; }

    public async Task InvokeAsync(HttpContext context, RequestDelegate next)
    {
        if (context.Request.Query.ContainsKey("hello"))
        {
            await context.Response.WriteAsync($"Hello World: {++Count}");
        }
        else
        {
            await next.Invoke(context);
        }
    }
}

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
    }

    public void Configure(IApplicationBuilder app, IHostingEnvironment env, IServiceProvider provider)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }

        app.UseMiddleware<HostMiddleware>();

        app.Run(async context =>
        {
            context.Response.StatusCode = 400;
            await context.Response.WriteAsync("Bad request.");
        });
    }

但是,当我运行此服务器时,我收到以下错误:

InvalidOperationException:未注册“WebApplication4.HostMiddleware”类型的服务。

开发者异常页面截图

为什么我会收到此错误? 如果我在项目中不使用依赖注入,为什么我的中间件需要注册任何服务?

更新:

出于某种原因,当我停止使用IMiddleware ,将InvokeAsync重命名为Invoke并以下列方式实现我的中间件时,不会发生此错误:

public class WmsHostMiddleware 
{
    private readonly RequestDelegate _next;

    public int Count { get; set; }

    public WmsHostMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    public async Task Invoke(HttpContext context)
    {
        if (context.Request.Query.ContainsKey("hello"))
        {
            await context.Response.WriteAsync($"Hello World: {++Count}");
        }
        else
        {
            await _next.Invoke(context);
        }
    }
}

问题仍然存在 - 为什么会发生这种情况? 有什么不同? 当我使用IMiddleware时,为什么需要注册服务。


I am trying to implement ASP.NET Core middleware, and this is the whole code I have in my project:

public class HostMiddleware : IMiddleware
{
    public int Count { get; set; }

    public async Task InvokeAsync(HttpContext context, RequestDelegate next)
    {
        if (context.Request.Query.ContainsKey("hello"))
        {
            await context.Response.WriteAsync($"Hello World: {++Count}");
        }
        else
        {
            await next.Invoke(context);
        }
    }
}

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
    }

    public void Configure(IApplicationBuilder app, IHostingEnvironment env, IServiceProvider provider)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }

        app.UseMiddleware<HostMiddleware>();

        app.Run(async context =>
        {
            context.Response.StatusCode = 400;
            await context.Response.WriteAsync("Bad request.");
        });
    }

However, when I run this server I get the following error:

InvalidOperationException: No service for type 'WebApplication4.HostMiddleware' has been registered.

developer exception page screenshot

Why do I get this error? Why would my middleware need to register any services if I don't use dependency injection in my project?

Update:

For some reason, this error does not occur when I stop using IMiddleware, rename InvokeAsync to Invoke and implement my middleware in the following way:

public class WmsHostMiddleware 
{
    private readonly RequestDelegate _next;

    public int Count { get; set; }

    public WmsHostMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    public async Task Invoke(HttpContext context)
    {
        if (context.Request.Query.ContainsKey("hello"))
        {
            await context.Response.WriteAsync($"Hello World: {++Count}");
        }
        else
        {
            await _next.Invoke(context);
        }
    }
}

The question is still open - why does this happen? What is the difference? Why do I need to register services when I use IMiddleware.


原文:https://stackoverflow.com/questions/48394756
更新时间:2024-02-26 08:02

最满意答案

您可以通过创建新对象来跟踪每个键的存在来计算每个键值出现的次数。

var set = {};

var changedArray = existingArray.map(function(d){
    // since each object has one key
    var key = Object.keys(d)[0];

    // if the key doesn't exist, add it.  if it does, increment it
    set[key] = (set[key] || 0) + 1

    // create the name
    var name = key + '_' + set[key];
    // create a new object with the given key
    var obj = {};
    obj[name] = d[key]; 
    return obj
});

编辑:

当然下面提出了一些好处,不要使用名称集。 你也可以通过添加if语句来避免第一个元素的'_1'

var name;
if (set[key] === 1 ) { 
   name = key;
} else {
   name = key + '_' + set[key];
}

至于只有重复的元素'_1' - 你总是可以使用最终计数再次循环。


You could count the number of times each key value appears by creating a new object to track the existence of each key.

var set = {};

var changedArray = existingArray.map(function(d){
    // since each object has one key
    var key = Object.keys(d)[0];

    // if the key doesn't exist, add it.  if it does, increment it
    set[key] = (set[key] || 0) + 1

    // create the name
    var name = key + '_' + set[key];
    // create a new object with the given key
    var obj = {};
    obj[name] = d[key]; 
    return obj
});

EDIT:

Of course some good points raised below, don't use the name set. also you could avoid the '_1' for the first element by adding an if statement like so

var name;
if (set[key] === 1 ) { 
   name = key;
} else {
   name = key + '_' + set[key];
}

As far as having a '_1' only on elements that repeat - you could always loop through again using the final counts.

相关问答

更多
  • 您可以使用以下代码: foreach ( array_keys($the_posted) as $k=>$v ) { $new_key = rand(); $new_posted[$new_key] = $the_posted[$v]; unset($the_posted[$v]) } 在这里,我们创建了一个新的数组$new_posted ,它将包含带有新键的数据,如下所示: Array ( [28228] => Array ( [0] = ...
  • 你需要将你的return移到你的循环之外: function getAllKeys(object){ var array = []; for(var key in object){ array.push(key); } return array; } var myObj = { name:"bellamy", age:25 }; getAllKeys(myObj); 这是因为你的函数会在第一次遇到return时立 ...
  • 您可以创建自己的“数组”类,其中封装了该逻辑。 例如: class Collection { public $items; public function __construct(array $items) { $this->items = $items; } public function lists($name) { return array_map(function ($item) use ($name) { ...
  • 你可以使用Array.prototype.find() modifyInput = (key) => { const match = this.props.parameters.find(x => x.key === key); // do stuff with matched object }; You can use Array.prototype.find() modifyInput = (key) => { const match = this.props.parameters.fin ...
  • 您可以使用for循环和内部map()方法为此创建函数以获取名称数组,并使用join()从值创建字符串。 const fruits = [{"name":"apple"},{"name":"kiwi"},{"name":"banana"},{"name":"orange"},{"name":"pineapple"},{"name":"coconut"},{"name":"peach"},{"name":"lemon"}] const pick = (arr, n) => { const r = [ ...
  • 您需要编写一个需要2个输入的递归函数 目的 前缀(未定义为第一级键) let record = [{"province":"string","city":"string","type":"alternative_address","address_line1":"string","post_code":"5858"},{"province":"string","city":"string","type":"alternative_address","post_code":"5858","embedeer": ...
  • 只需创建关键item.id + item.status ,然后这是一个简单的任务 const res = Object.values(arr.reduce((a, b) => { a[b.id + b.status] = Object.assign(b, {tally: (a[b.id + b.status] || {tally: 0}).tally + 1}); return a; }, {})); console.log(res);