📜  解释 ASP.NET 中的 ConfigureServices 和 Configure 方法?

📅  最后修改于: 2022-05-13 01:56:17.352000             🧑  作者: Mango

解释 ASP.NET 中的 ConfigureServices 和 Configure 方法?

在本文中,我们将了解什么是 Configure 和 ConfigureService 方法。基本上,这两种方法在启动类中起着非常重要的作用。这个类的基线是减少应用程序对服务器的依赖。实际上,需要 Startup 类来定义两个将由 ASP.NET Core 自动调用的方法。它们是 ConfigureServices 方法和 Configure 方法。

在 Startup 类中,我们实际上做了两件事:

  • 配置服务():用于向容器添加服务并配置这些服务。基本上,服务是一个用于应用程序中常见消费的组件。有MVC、EF核心、身份等框架服务。但也有特定于应用程序的应用程序服务,例如发送邮件服务。
  • Configure():它用于指定 asp.net 核心应用程序将如何响应单个请求。通过这个,我们实际上构建了 HTTP 请求管道

示例:打开 program.cs 文件。如您所见,代码:

C#
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Hosting;
  
namespace Avengers_ListApplicaton {
    public class Program {
        public static void Main(string[] args) {
            CreateHostBuilder(args).Build().Run();
        }
  
        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup ();
            });
    }
}


C#
namespace Avengers_ListApplicaton {
    public class Startup {
        
        // This method gets called by the runtime. 
          // Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services) {
            // Register services here through dependency injection
        }
  
        // This method gets called by the runtime. 
          // Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, 
                              IWebHostEnvironment env) {
            
            // Add middlware components here
            if (env.IsDevelopment()) {
                app.UseDeveloperExceptionPage();
            }
            app.UseRouting();
            app.UseEndpoints(endpoints => {
                endpoints.MapGet("/",async Context => {
                    await context.Response.WriteAsync("Hello World!");
                });
            });
        }
    }
}


C#
public class ToDoModel {
    public int Id { get; set; }
    [Required]
    [MaxLength(50)]
    public string Wish{ get; set; }
}


C#
public class ApplicationDbContext : DbContext {
    public ApplicationDbContext(
          DbContextOptions options)
             : base(options) {
    }
         
    public DbSet ToDoData { get; set; }
}


C#
public void ConfigureServices(IServiceCollection services) {
      services.AddMvc();
    services.AddDbContext(
        options => options.UseInMemoryDatabase("ToDoList"));
}


C#
public void Configure(IApplicationBuilder app, 
                      IWebHostEnvironment env) {
    if (env.IsDevelopment()) {
        app.UseDeveloperExceptionPage();
    }
    else {
        app.UseExceptionHandler("/Home/Error");
    }
    app.UseRouting();
  
    app.UseEndpoints(endpoints => {
        endpoints.MapDefaultControllerRoute();
    });
}


C#
public class HomeController : Controller {
    public IActionResult Index() {
        return View("Index");
    }
    public IActionResult Error() {
        return View("Error");
    }
}


HTML
@{
    ViewData["Title"] = "Error";
}
  

Error

     

An error has occurred. Please try again.



HTML
@model IEnumerable
  
@{
    ViewData["Title"] = "Index";
}
  

Index

   @Html.ActionLink("View Task List", "Index", "ToDo")


C#
public class ToDoController : Controller
    {
        private readonly ApplicationDbContext _context;
  
        public ToDoController(ApplicationDbContext context)
        {
             _context = context;
        }
        public IActionResult Index()
        {
            var model=_context.ToDoData.ToList();
            return View("Index",model);
        }
        [HttpGet]
        public IActionResult Create()
        {
            return View("Create");
        }
        [HttpPost]
        public IActionResult Create(ToDoModel todo)
        {
            _context.ToDoData.Add(todo);
            _context.SaveChanges();
            return RedirectToAction("Index");
        }
         
    }


  • 在 main函数中,设置了一个主机,它将配置一个服务器和一个请求处理管道。
  • 我们正在调用CreateHostBuilder ,它将使用Host.CreateDefaultBuilder() 设置具有一些默认值的应用程序。
  • 在 Main 中,我们将调用CreateHostBuilder ,并在其中创建一个主机,然后运行我们的应用程序。您可以看到我们首先要在主机上调用CreateDefaultBuilder方法。 CreateDefaultBuilder 方法将设置一个已经有相当多默认值的主机构建器。新的网络主机将再次使用默认值进行配置。
  • 这里发生的另一件非常重要的事情是我们正在使用UseStartup方法指定 Startup 类。我们将 Startup 类(即UseStartup )作为类型传递,它将是实际执行应用程序配置的类型。

Startup.cs:我们看一下Startup类。正如我们看到的ConfigureServicesConfigure方法。

C#

namespace Avengers_ListApplicaton {
    public class Startup {
        
        // This method gets called by the runtime. 
          // Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services) {
            // Register services here through dependency injection
        }
  
        // This method gets called by the runtime. 
          // Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, 
                              IWebHostEnvironment env) {
            
            // Add middlware components here
            if (env.IsDevelopment()) {
                app.UseDeveloperExceptionPage();
            }
            app.UseRouting();
            app.UseEndpoints(endpoints => {
                endpoints.MapGet("/",async Context => {
                    await context.Response.WriteAsync("Hello World!");
                });
            });
        }
    }
}

在 ConfigureServices 方法中:

  • 在首先调用的 ConfigureServices 方法中,我们将为应用程序注册服务
  • 如您所见,在上面的代码片段中,ConfigureService 中最初没有代码,但无论如何,这些内置服务已经可以注入,因此我们可以在此方法中添加所有服务并注入其他代码段。
  • 这个容器可以通过 IServiceProvider 接口获得,这里看到的服务集合就是它所管理的服务集合。因此,我们可以在 ConfigureServices 方法中将服务添加到应用程序中的托管服务集合中。服务是对应用程序的其他部分具有固定功能的对象
  • 在那里,我们需要添加我们将在应用程序中使用的所有服务。这些可以是内置服务,也可以是我们自己的服务。这是我们将使用 ASP.NET Core 内置的依赖注入系统注册所有依赖项的地方。

在配置方法中:

这个在配置 service 方法后调用,因为它使用的是在 configureServices 方法中注册和配置的服务

  • 将配置 HTTP 请求管道。如您所见,这里有一些默认值,请注意第一行将使用环境检查。使用依赖注入,此方法将接收一个WebHostEnvironment实例,然后我们将检查环境。
  • env.IsDevelopment 这表示这个对开发者友好的异常页面中间件只有在我们在开发环境中运行时才会被添加。 developerExceptionPage 中间件不是我们想让大家看到的。我们只希望在开发应用程序期间跟踪异常堆栈。UseDeveloperExceptionPage 语句通过向其中添加 developerExceptionPage 中间件来配置请求管道,因此现在当抛出异常时,您在代码片段中看到的代码片段将处理它。
  • 现在我要添加另一段代码来处理不属于开发环境的异常。 useExceptionHandler 中间件捕获异常,记录它们,然后重新执行请求。这不会向我们显示对开发人员友好的异常页面,并且不会暴露堆栈跟踪。现在您可以通过更改环境变量进行检查。
  • 字符串,来到下一个UseRoutingUseEnpoints 。它实际上负责在向应用程序发送请求时将响应作为输出提供基本上使 MVC 能够响应传入的请求,它需要将传入的请求映射到将执行的正确代码

现在让我们看看,如何装饰startup.cs文件中的服务。创建一个简单的项目,

在这个项目中,我不会解释或定义每一个步骤。我们将只关注 startup.cs 文件

所以让我们开始吧:

第一步:新建一个asp.net core web应用项目,选择模板MVC

第二步:在模型文件夹下创建模型类,即ToDoModel

C#

public class ToDoModel {
    public int Id { get; set; }
    [Required]
    [MaxLength(50)]
    public string Wish{ get; set; }
}

第 3 步:创建类 ApplicationDbContext |继承 DbContext 类 |添加构造函数 |将模型类添加到 ApplicationDbContext

C#

public class ApplicationDbContext : DbContext {
    public ApplicationDbContext(
          DbContextOptions options)
             : base(options) {
    }
         
    public DbSet ToDoData { get; set; }
}

注意:在这个演示中,我将使用 InMemory 数据库和 Entity Framework Core。所以你必须安装它的nuget包,即Microsoft.EntityFrameworkCore.InMemory。

第 4 步:现在让我们在 ConfigureServices 方法中注册服务,

  • 调用 AddMvc() 添加对 MVC 中间件的支持。
  • 使用 .UseInMemoryDatabase(“ToDoList”) 的参数调用 AddDbContext<> 以将 EntityFramework 配置到 DbContext 类。

C#

public void ConfigureServices(IServiceCollection services) {
      services.AddMvc();
    services.AddDbContext(
        options => options.UseInMemoryDatabase("ToDoList"));
}

第 5 步:在 Configure 方法中,完全删除现有代码并将其替换为对 app.UseRouting() 的调用,并在 UseRouting 之后添加对 app.UseEndpoints() 的调用。

UseRouting:这个中间件组件用于路由请求。

UseEndpoints:此中间件组件将允许将请求路由到应用程序中的正确端点。

C#

public void Configure(IApplicationBuilder app, 
                      IWebHostEnvironment env) {
    if (env.IsDevelopment()) {
        app.UseDeveloperExceptionPage();
    }
    else {
        app.UseExceptionHandler("/Home/Error");
    }
    app.UseRouting();
  
    app.UseEndpoints(endpoints => {
        endpoints.MapDefaultControllerRoute();
    });
}

第 6 步:在 UseRouting 之前的 Configure 方法中,使用 IsDevelopment() 方法检查环境是否设置为 Development

  • 如果是,它应该调用 app.UseDeveloperExceptionPage() 来获取错误页面的堆栈跟踪。
  • 否则,它应该调用 app.UseExceptionHandler() 并将参数“/Home/Error”传递给它
  • UseDeveloperExceptionPage:这将允许在我的应用程序中使用开发人员异常页面,以便在开发过程中获得有用的信息。
  • UseExceptionHandler:此中间件组件用于启用添加自定义用户友好的错误消息。

步骤07:创建控制器添加操作方法,即 Index 和 Error |

C#

public class HomeController : Controller {
    public IActionResult Index() {
        return View("Index");
    }
    public IActionResult Error() {
        return View("Error");
    }
}

步骤 08 :在共享文件夹中创建通用错误视图以及将视图添加到索引方法 |在该索引视图上添加 ToDoList 的链接

错误操作方法查看:

HTML

@{
    ViewData["Title"] = "Error";
}
  

Error

     

An error has occurred. Please try again.

Homecontroller 视图的索引操作方法:

HTML

@model IEnumerable
  
@{
    ViewData["Title"] = "Index";
}
  

Index

   @Html.ActionLink("View Task List", "Index", "ToDo")

第 9 步:再创建一个控制器 |创建 ApplicationDbContext 类型的字段。 |创建构造函数并将值设置为传递给构造函数的参数 |为列表创建操作方法 |获取创建 |发布创建并基于它添加视图

C#

public class ToDoController : Controller
    {
        private readonly ApplicationDbContext _context;
  
        public ToDoController(ApplicationDbContext context)
        {
             _context = context;
        }
        public IActionResult Index()
        {
            var model=_context.ToDoData.ToList();
            return View("Index",model);
        }
        [HttpGet]
        public IActionResult Create()
        {
            return View("Create");
        }
        [HttpPost]
        public IActionResult Create(ToDoModel todo)
        {
            _context.ToDoData.Add(todo);
            _context.SaveChanges();
            return RedirectToAction("Index");
        }
         
    }

输出:

输出 GIF

最后的想法,

申请启动流程

让我们快速强调一些要点文章。应用程序从调用 Startup 类中的 main函数开始。然后,我们使用启动调用指定哪个是我们的 Startup 类。在 Startup 类中,首先调用 ConfigureServices,允许我们注册要在应用程序中使用的服务。然后,在设置请求管道的地方调用 Configure 方法。毕竟,我们的应用程序已经启动并运行,并准备好处理传入的请求。

这就是配置和配置服务方法的全部内容。