草庐IT

c# - mvc6中app、服务和中间件的区别

coder 2023-07-13 原文

我试图理解 MVC6 中中间件的概念。这对我来说仍然有点模糊。我真的看不出您在 Startup 类中获得的几个“标准”变量之间的区别。

据我所知,有 3 种不同的方法可以告诉应用程序它应该使用特定的中间件?

你可以通过服务调用中间件使用。但这似乎只是为了“添加”中间件?

services.AddMvc();

// Add other services
services.AddScoped<IMyCountriesRepository, MyCountriesRepository>();
services.AddScoped<IEmailer, Emailer>();

然后你就有了 IApplicationBuilder 应用。这是要实际使用服务中加载的中间件?所以你可以这样调用它:

app.UseMvc();
app.UseErrorPage(...);
app.UseIdentity(); // cookie authentication 

然后有一种方法可以像这样加载和使用中间件:

app.UseMiddleware<MyCustomMiddleware>();

三种类型的注册/使用中间件有什么好处?它们之间的确切区别是什么?

最佳答案

我会区分添加服务和添加中间件。

添加服务

这基本上是将您的功能所需的类注册到 ASP .Net 5 中构建的依赖项注入(inject)容器中。(IServiceCollection 接口(interface))

您可以做的最简单的事情就是手动将它们一一添加,如下所示:

services.AddScoped<IMyCountriesRepository, MyCountriesRepository>();
services.AddScoped<IEmailer, Emailer>();

如果您要构建更复杂的应用程序或自包含框架,您可能需要创建一个函数来注册所需的所有服务。一个好的方法是创建一个扩展方法:

public static void AddMyServices(this IServiceCollection services)
{
    services.AddScoped<IMyCountriesRepository, MyCountriesRepository>();
    services.AddScoped<IEmailer, Emailer>();
    ...
}

//register all your services just by running the ext method:
services.AddMyServices();

这正是services.AddMvc();正在做。

In a more flexible way as it allows you to pass a lambda to further customize default services like the model binders (Like services.AddMvc(opts => opts.ModelBinders ...)) and is returning an IMvcBuilder you can use to further customize it things like the view engines (Like services.AddMvc().AddViewOptions(opts => opts.ViewEngines ...)).

添加中间件

ASP .Net 5 不是基于 HTTP 模块和处理程序,而是基于中间件的 OWIN 思想。有一个 nice blog entryAndrei Dzimchuk 描述的中间件很好地总结了它:

Middleware – Pass through components that form a pipeline between a server and application to inspect, route, or modify request and response messages for a specific purpose.

And this definition applies to ASP.NET 5 as well. Middleware can be thought of as both HTTP modules and handlers that we've had in classic ASP.NET. Some middleware would implement various intermediate tasks when processing requests such as authentication, session state retrieval and persistence, logging and so on. Some of them would be the ultimate request handlers that would produce responses.

所以现在您想将自己的行为添加到 ASP 管道中。

最简单的就是定义一个内联中间件:

app.Use(async (context, next) =>
{
    //do something before passing the request to the next middleware
    await next.Invoke();
});

您也可以create your own middleware class并注册:

app.UseMiddleware<MyMiddleware>();

最后,您可以再次定义扩展方法来封装复杂的设置逻辑。

This is what app.UseMvc() does. It lets you define your routes and it is then adding the routing middleware by calling app.UseRouter(). As you can see, the implementation of app.UseRouter adds the RouterMiddleware into the pipeline with the call to builder.UseMiddleware<RouterMiddleware>(router);

您的中间件所需的任何服务之前都已注册。这意味着它们将通过内置的 DI 容器供您的中间件使用。


最终结果是该框架使您可以更轻松地混合和匹配应用程序所需的组件(服务)和行为(中间件),仅包括您需要的部分。

关于c# - mvc6中app、服务和中间件的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33126665/

有关c# - mvc6中app、服务和中间件的区别的更多相关文章

  1. ruby - 使用 ruby​​ 和 savon 的 SOAP 服务 - 2

    我正在尝试使用ruby​​和Savon来使用网络服务。测试服务为http://www.webservicex.net/WS/WSDetails.aspx?WSID=9&CATID=2require'rubygems'require'savon'client=Savon::Client.new"http://www.webservicex.net/stockquote.asmx?WSDL"client.get_quotedo|soap|soap.body={:symbol=>"AAPL"}end返回SOAP异常。检查soap信封,在我看来soap请求没有正确的命名空间。任何人都可以建议我

  2. ruby - 具有身份验证的私有(private) Ruby Gem 服务器 - 2

    我想安装一个带有一些身份验证的私有(private)Rubygem服务器。我希望能够使用公共(public)Ubuntu服务器托管内部gem。我读到了http://docs.rubygems.org/read/chapter/18.但是那个没有身份验证-如我所见。然后我读到了https://github.com/cwninja/geminabox.但是当我使用基本身份验证(他们在他们的Wiki中有)时,它会提示从我的服务器获取源。所以。如何制作带有身份验证的私有(private)Rubygem服务器?这是不可能的吗?谢谢。编辑:Geminabox问题。我尝试“捆绑”以安装新的gem..

  3. ruby-on-rails - 启动 Rails 服务器时 ImageMagick 的警告 - 2

    最近,当我启动我的Rails服务器时,我收到了一长串警告。虽然它不影响我的应用程序,但我想知道如何解决这些警告。我的估计是imagemagick以某种方式被调用了两次?当我在警告前后检查我的git日志时。我想知道如何解决这个问题。-bcrypt-ruby(3.1.2)-better_errors(1.0.1)+bcrypt(3.1.7)+bcrypt-ruby(3.1.5)-bcrypt(>=3.1.3)+better_errors(1.1.0)bcrypt和imagemagick有关系吗?/Users/rbchris/.rbenv/versions/2.0.0-p247/lib/ru

  4. ruby-on-rails - s3_direct_upload 在生产服务器中不工作 - 2

    在Rails4.0.2中,我使用s3_direct_upload和aws-sdkgems直接为s3存储桶上传文件。在开发环境中它工作正常,但在生产环境中它会抛出如下错误,ActionView::Template::Error(noimplicitconversionofnilintoString)在View中,create_cv_url,:id=>"s3_uploader",:key=>"cv_uploads/{unique_id}/${filename}",:key_starts_with=>"cv_uploads/",:callback_param=>"cv[direct_uplo

  5. ruby - 触发器 ruby​​ 中 3 点范围运算符和 2 点范围运算符的区别 - 2

    请帮助我理解范围运算符...和..之间的区别,作为Ruby中使用的“触发器”。这是PragmaticProgrammersguidetoRuby中的一个示例:a=(11..20).collect{|i|(i%4==0)..(i%3==0)?i:nil}返回:[nil,12,nil,nil,nil,16,17,18,nil,20]还有:a=(11..20).collect{|i|(i%4==0)...(i%3==0)?i:nil}返回:[nil,12,13,14,15,16,17,18,nil,20] 最佳答案 触发器(又名f/f)是

  6. ruby - RuntimeError(自动加载常量 Apps 多线程时检测到循环依赖 - 2

    我收到这个错误:RuntimeError(自动加载常量Apps时检测到循环依赖当我使用多线程时。下面是我的代码。为什么会这样?我尝试多线程的原因是因为我正在编写一个HTML抓取应用程序。对Nokogiri::HTML(open())的调用是一个同步阻塞调用,需要1秒才能返回,我有100,000多个页面要访问,所以我试图运行多个线程来解决这个问题。有更好的方法吗?classToolsController0)app.website=array.join(',')putsapp.websiteelseapp.website="NONE"endapp.saveapps=Apps.order("

  7. ruby-on-rails - 每次我尝试部署时,我都会得到 - (gcloud.preview.app.deploy) 错误响应 : [4] DEADLINE_EXCEEDED - 2

    我是Google云的新手,我正在尝试对其进行首次部署。我的第一个部署是RubyonRails项目。我基本上是在关注thisguideinthegoogleclouddocumentation.唯一的区别是我使用的是我自己的项目,而不是他们提供的“helloworld”项目。这是我的app.yaml文件runtime:customvm:trueentrypoint:bundleexecrackup-p8080-Eproductionconfig.ruresources:cpu:0.5memory_gb:1.3disk_size_gb:10当我转到我的项目目录并运行gcloudprevie

  8. ruby-on-rails - `a ||= b` 和 `a = b if a.nil 之间的区别? - 2

    我正在检查一个Rails项目。在ERubyHTML模板页面上,我看到了这样几行:我不明白为什么不这样写:在这种情况下,||=和ifnil?有什么区别? 最佳答案 在这种特殊情况下没有区别,但可能是出于习惯。每当我看到nil?被使用时,它几乎总是使用不当。在Ruby中,很少有东西在逻辑上是假的,只有文字false和nil是。这意味着像if(!x.nil?)这样的代码几乎总是更好地表示为if(x)除非期望x可能是文字false。我会将其切换为||=false,因为它具有相同的结果,但这在很大程度上取决于偏好。唯一的缺点是赋值会在每次运行

  9. c# - 如何在 ruby​​ 中调用 C# dll? - 2

    如何在ruby​​中调用C#dll? 最佳答案 我能想到几种可能性:为您的DLL编写(或找人编写)一个COM包装器,如果它还没有,则使用Ruby的WIN32OLE库来调用它;看看RubyCLR,其中一位作者是JohnLam,他继续在Microsoft从事IronRuby方面的工作。(估计不会再维护了,可能不支持.Net2.0以上的版本);正如其他地方已经提到的,看看使用IronRuby,如果这是您的技术选择。有一个主题是here.请注意,最后一篇文章实际上来自JohnLam(看起来像是2009年3月),他似乎很自在地断言RubyCL

  10. ruby-on-rails - 如何重命名或移动 Rails 的 README_FOR_APP - 2

    当我在我的Rails应用程序根目录中运行rakedoc:app时,API文档是使用/doc/README_FOR_APP作为主页生成的。我想向该文件添加.rdoc扩展名,以便它在GitHub上正确呈现。更好的是,我想将它移动到应用程序根目录(/README.rdoc)。有没有办法通过修改包含的rake/rdoctask任务在我的Rakefile中执行此操作?是否有某个地方可以查找可以修改的主页文件的名称?还是我必须编写一个新的Rake任务?额外的问题:Rails应用程序的两个单独文件/README和/doc/README_FOR_APP背后的逻辑是什么?为什么不只有一个?

随机推荐