As 《ASP.NET Core 3 The framework reveals 》 Upgraded version ,《ASP.NET Core 6 The framework reveals 》 There are many new chapters , At the same time, make a lot of modifications to the existing content . Although this book aims at ASP.NET Core The architecture design and implementation principle of the framework are analyzed , But what it provides 258 An example The demonstration can be used as an introductory material , This series will extract and summarize these demonstration examples separately . For wanting to learn ASP.NET Core Classmate , If you feel no need “ The bricks are so deep ”, You can have a look . This film provides 20 A simple demonstration example basically covers ASP.NET Core 6 Basic programming mode , We will not only use them to demonstrate against the console 、API、MVC、gRPC Application construction and programming , Will also demonstrate Dapr stay .NET 6 Application in . besides , this 20 Examples also cover dependency injection 、 configuration option 、 Application of logging .
[101] Create... From the command line .NET Program ( Source code )
[102] use Minimal API structure ASP.NET Core Program ( Source code )
[103] One step to create WebApplication object ( Source code )
[104] The original form of middleware ( Source code )
[105] Using middleware delegation variants (1)( Source code )
[106] Using middleware delegation variants (2)( Source code )
[107] Define strongly typed middleware types ( Source code )
[108] Define contract based Middleware types ( Constructor injection )( Source code )
[109] Define contract based Middleware types ( Methods to inject )( Source code )
[110] Configured applications ( Source code )
[111]Options Application ( Source code )
[112] The application of log ( Source code )
[101] Create... From the command line .NET Program
We follow the picture 1 Execute... In the manner shown “dotnet new” command (dotnet new console -n App) Create a file called “App” Console program . After the command is executed, a subdirectory named by the specified application name will be created in the current working directory , And store the generated files inside .
chart 1 perform “dotnet new” Command to create a console program
.csproj The document is finally MSBuild Service , This file provides relevant configurations to control MSBuild Compile and publish the current project . The following is App.csproj The whole content of the document , If you've ever looked at tradition .NET Framework Under the .csproj file , You will be amazed at this App.csproj The conciseness of the document content ..NET 6 The simplicity of the project file under comes from SDK Application . Different application types will adopt different SDK, For example, the console application we created adopts SDK by “Microsoft.NET.Sdk”,ASP.NET The application will adopt another name “Microsoft.NET.Sdk.Web” Of SDK.SDK It is equivalent to formulating a plan for a certain type of project MSBuild The benchmark configuration of , If in the project file <Project> The root node has specific SDK, It means inheriting this benchmark configuration directly .
1 <Project Sdk="Microsoft.NET.Sdk">
2 <PropertyGroup>
3 <OutputType>Exe</OutputType>
4 <TargetFramework>net6.0</TargetFramework>
5 <ImplicitUsings>enable</ImplicitUsings>
6 <Nullable>enable</Nullable>
7 </PropertyGroup>
8 </Project>
This is shown in the code snippet above , Project related attributes can be grouped and defined in <PropertyGroup> Under the node . This App.csproj The file defines four attributes , among OutputType and TargetFramework Attribute indicates the compile output type and the target framework used . Because we created a target for .NET 6 The executable console application , therefore TargetFramework and OutputType Set as “net6.0” and “Exe”. Project ImplicitUsings Properties and C# 10 The one provided is called “ Global namespace ” New features , The other one is called Nullable The nature of C# With a name called “ Null value (Null) verification ” Related to the characteristics of .
The following is generated in the project directory Program.cs The content of the document . It can be seen that there are only two lines of text in the whole document , One line is still a comment . The only line of code calls Console The static method of type will string “Hello, World!” Output to the console . It shows C# 10 The other is called “ Top level statement (Top-level Statements)” New features —— The code of the entry program can exist independently as a top-level statement .
1 // See https://aka.ms/new-console-template for more information
2 Console.WriteLine("Hello, World!");
in the light of .NET The compilation and operation of the application can also be executed “dotnet.exe” The command line does . Pictured 2 Shown , After taking the project root directory as the working directory , We execute “dotnet build” Command to compile the console application . Because the default is Debug Compile mode , So the compiled assembly is stored in “\bin\Debug\” Under the table of contents . The same application can adopt multiple target frameworks , Assemblies compiled for different target frameworks will be placed in different directories . Because we created for .NET 6.0 Applications for , So the final generated assembly is saved in “\bin\Debug\net6.0\” Under the table of contents .
chart 2 perform “dotnet build” Command to compile a console program
If you look at the compiled output directory , You can find two people with the same name (App) Assembly file , One is App.dll, The other is App.exe, The latter will be much larger in size .App.exe Is an executable that can run directly , and App.dll Just a simple DLL , With the help of the command line dotnet To perform .
Pictured 3 Shown , When we execute “dotnet run” After the command , The compiled program is executed ,“Hello, World!” The string is printed directly on the console . perform “dotnet run” There is no need to explicitly execute the command before starting the program “dotnet build” Command to compile the source code , Because this command will automatically trigger the compile operation . In execution “dotnet” When the command starts the application set , We can also directly specify the path to start the assembly (“dotnet bin\Debug\net6.0\App.dll”). actually dotnet run Mainly used in development testing ,dotnet {AppName}.dll The way is to deploy the environment ( such as Docker Containers ) The starting mode adopted in .
chart 3 perform dotnet Command to run a console program
[102] use Minimal API structure ASP.NET Core Program
Use the front dotnet new The command creates a simple console program , Next, we will transform it into a ASP.NET Core application . We said that before , Different application types will adopt different SDK, So we modify it directly App.csproj The file will be SDK Set to “Microsoft.NET.Sdk.Web”. Because there is no need to use the generated .exe File to start ASP.NET Core application , So we should XML Elements <OutputType>Exe</OutputType> from <PropertyGroup> Delete... From node .
1 <Project Sdk="Microsoft.NET.Sdk.Web">
2 <PropertyGroup>
3 <TargetFramework>net6.0</TargetFramework>
4 <ImplicitUsings>enable</ImplicitUsings>
5 <Nullable>enable</Nullable>
6 </PropertyGroup>
7 </Project>
ASP.NET Core (Core) Application hosting (Hosting) Experienced three major changes , Due to the latest bearing mode API The most concise and least dependent , We call it “Minimal API” . This book is in addition to 16 Chapter “ Application hosting ( On )” It will involve two other load-bearing modes , All demonstration examples provided in this book will use Minimal API. The following is the first one written in this programming mode Hello World Program .
1 RequestDelegate handler = context => context.Response.WriteAsync("Hello, World!");
2 WebApplicationBuilder builder = WebApplication.CreateBuilder(args);
3 WebApplication app = builder.Build();
4 app.Run(handler: handler);
5 app.Run();
The above code snippet involves three important objects , among WebApplication Object represents the hosted application ,Minimal API use “ Builder (Builder)” Pattern to build it , This builder is embodied as a WebApplicationBuilder object . As the code snippet shows , We call WebApplication Static factory method of type CreateBuilder Created a WebApplicationBuilder object , Parameters of this method args Represents an array of command line parameters . When calling this object Build Methods will WebApplication After the object is built , We called its Run Extend the method and use a RequestDelegate Object as its parameter .RequestDelegate Although it is a simple delegate type , But it is in ASP.NET Core Special position in the framework system , Now let's make a brief introduction to it .
When one ASP.NET Core After starting , It will use the registered server to bind to the specified port for request listening . After receiving the arrival request , One passes HttpContext The context object represented by the object will be created . We can not only extract all the information related to the current request from this context , You can also directly use this context to complete the response to the request . On this point, we can learn from HttpContext This abstract class has the following two core properties Request and Response see .
1 public abstract class HttpContext
2 {
3 public abstract HttpRequest Request { get }
4 public abstract HttpResponse Response { get }
5 ...
6 }
because ASP.NET Core Application processing for requests is always in one HttpContext In context , So the processor for the request can be represented as a Func<HttpContext, Task> Delegation of type . Because such delegation will be widely used , therefore ASP.NET Core Directly define a special delegate type , Is what we use in the program RequestDelegate. From the following for RequestDelegate The definition of type can be seen , It is essentially a Func<HttpContext, Task> entrust .
1 public delegate Task RequestDelegate(HttpContext context);
Return to the demo program again . We created one first RequestDelegate entrust , The corresponding target method will write a string in the response output stream “Hello, World!” . We call this delegate as a parameter WebApplication Object's Run Extension method , This call can be understood as taking this delegate as the processor of all requests , All requests received will be processed through this delegate . The demo program finally calls WebApplication Another no parameter Run The extension method is to start the hosted application . stay Visual Studio Next , We can just press F5( perhaps Ctrl + F5) Start the program , Of course, for the command line “dotnet run” The application startup mode of the command is still valid , Most of the demonstration examples provided in this book adopt this method . Pictured 4 Shown , After we start the program from the command line , The console appears ASP.NET Core Log output from the framework , The log indicates that the application has started at the default two endpoints (http://localhost:5000 and https://localhost:5001) Listening request . We used the browser to send two requests for these two endpoints , Get consistent response . From the content of the response, we can see that the application uses what we specify RequestDelegate Entrusted to handle the request .
chart 4 Launch the application and access it with a browser
[103] One step to create WebApplication object
The program demonstrated above first calls the definition in WebApplication Static factory method of type CreateBuilder Create a WebApplicationBuilder object , Then use the latter to build a representative hosting application WebApplication object .WebApplicationBuilder Provides a lot to build WebApplication Set up API, But our demonstration examples do not use them , At this point, we can directly call the static factory method Create take WebApplication Object creation . In the rewriting procedure shown below , We directly define the request processor as a local static method HandleAsync.
1 var app = WebApplication.Create(args);
2 app.Run(handler: HandleAsync);
3 app.Run();
4
5 static Task HandleAsync(HttpContext httpContext) => httpContext.Response.WriteAsync("Hello, World!");
[104] The original form of middleware
Carrying ASP.NET Core The application is finally embodied in the request processing pipeline built by the registration middleware . The server receives the request and will successfully build HttpContext After the context , The request will be delivered to this pipeline for processing . After the pipeline completes the processing task , Control returns to the server again , It will convert the processing result into a response and send it . From the perspective of application programming , This pipeline is embodied in the above RequestDelegate entrust , The single middleware that makes up it is another type Func<RequestDelegate,RequestDelegate> Commission of , The input and output of this delegate is a RequestDelegate object , The former represents the pipeline built by subsequent middleware , The latter represents the new pipeline generated after the current middleware is included in this pipeline . In the example shown above , We will RequestDelegate Delegate is called as a parameter WebApplication Of Run Extension method , We said at that time that this was to set up a request processor for the application . In fact, this statement is not accurate , This method is just to register a middleware . To be more specific , This method is used to register the middleware at the end of the pipeline . In order to let readers experience the processing of requests by middleware and pipelines , We have rewritten the above demo application as follows .
1 var app = WebApplication.Create(args);
2 IApplicationBuilder appBuilder = app;
3 appBuilder
4 .Use(middleware: HelloMiddleware)
5 .Use(middleware: WorldMiddleware);
6 app.Run();
7
8 static RequestDelegate HelloMiddleware(RequestDelegate next)
9 => async httpContext => {
10 await httpContext.Response.WriteAsync("Hello, ");
11 await next(httpContext);
12 };
13
14 static RequestDelegate WorldMiddleware(RequestDelegate next)
15 => httpContext => httpContext.Response.WriteAsync("World!");
Because the middleware is embodied as a Func<RequestDelegate,RequestDelegate> entrust , So we use the two local static methods defined above that have consistent declarations with the delegate type HelloMiddleware and WorldMiddleware To represent the corresponding middleware . We will complete the text “Hello, World!” Split into “Hello, ” and “World!” Two paragraphs , Write the response output stream by the above two endpoints . After creating a representative hosting application WebApplication After object , We convert it into IApplicationBuilder Interface type , And call it Use Method completes the registration of the above two middleware ( because WebApplication The type explicitly implements the definition in IApplicationBuilder Interface Use Method , We have to do type conversion ). If the browser uses the same address to request the launched Application , We can still get the picture 4 The response content shown .
[105] Using middleware delegation variants (1)
Although middleware is always embodied as a Func<RequestDelegate,RequestDelegate> entrust , But we can use different forms to define Middleware in the development process , For example, we can define middleware as the following two types of delegates . These two delegate contents use RequestDelegate and Func<Task> Complete calls to subsequent pipelines .
- Func<HttpContext, RequestDelegate, Task>
- Func<HttpContext, Func<Task>, Task>
Let's now show how to use Func<HttpContext, RequestDelegate, Task> Define Middleware in the form of delegation . This is shown in the following code snippet , We will HelloMiddleware and WorldMiddleware Replaced with Func<HttpContext, RequestDelegate, Task> Delegate types have local static methods that are consistently declared .
1 var app = WebApplication.Create(args);
2 app
3 .Use(middleware: HelloMiddleware)
4 .Use(middleware: WorldMiddleware);
5 app.Run();
6
7 static async Task HelloMiddleware(HttpContext httpContext, RequestDelegate next)
8 {
9 await httpContext.Response.WriteAsync("Hello, ");
10 await next(httpContext);
11 };
12
13 static Task WorldMiddleware(HttpContext httpContext, RequestDelegate next) => httpContext.Response.WriteAsync("World!");
[106] Using middleware delegation variants (2)
The following program replaces these two middleware with Func<HttpContext, Func<Task>, Task> Delegate types have consistently declared local methods . When we call WebApplication Of Use Methods combine these two “ variant ” When registering as middleware , This method internally converts the provided delegate into Func<RequestDelegate,RequestDelegate> type .
1 var app = WebApplication.Create(args);
2 app
3 .Use(middleware: HelloMiddleware)
4 .Use(middleware: WorldMiddleware);
5 app.Run();
6
7 static async Task HelloMiddleware(HttpContext httpContext, Func<Task> next)
8 {
9 await httpContext.Response.WriteAsync("Hello, ");
10 await next();
11 };
12
13 static Task WorldMiddleware(HttpContext httpContext, Func<Task> next) => httpContext.Response.WriteAsync("World!");
[107] Define strongly typed middleware types
When we try to use a custom middleware to complete some request processing function , In fact, middleware is rarely defined as the above three forms of delegation , Basically, it will be defined as a specific type . Middleware types are defined , One is to directly realize IMiddleware Interface , This book calls it “ Strong type ” How to define middleware of . Let's define a simple middleware type in this way . No matter in defining middleware types , Or define other service types , If they have dependencies on other services , We all use dependency injection (Dependency Injection) The way to integrate them . Whole ASP.NET Core The framework is built on the dependency injection framework , Dependency injection has become ASP.NET Core The most basic programming method . Next, we will demonstrate the application of dependency injection in custom middleware types .
In the example shown earlier , We use middleware to write “ Hard encoding ” Greetings specified in the way “Hello, World!”, Now we choose the following IGreeter The service represented by the interface provides the corresponding greetings according to the specified time ,Greeter Type is the default implementation of this interface . It needs to be explained in advance , All demonstration examples provided in this book are in “App” name , Independently defined types will be defined in the agreed “App” Under the namespace . To save space , The type definition code fragment provided next will no longer provide the namespace , When the application program starts, it appears for “App” Don't be surprised when importing namespaces .
1 namespace App
2 {
3 public interface IGreeter
4 {
5 string Greet(DateTimeOffset time);
6 }
7
8 public class Greeter : IGreeter
9 {
10 public string Greet(DateTimeOffset time) => time.Hour switch
11 {
12 var h when h >= 5 && h < 12 => "Good morning!",
13 var h when h >= 12 && h < 17 => "Good afternoon!",
14 _ => "Good evening!"
15 };
16 }
17 }
We define the following as GreetingMiddleware The middleware type of . As the code snippet shows , This type implements IMiddleware Interface , The processing of requests is implemented in InvokeAsync In the method . We are GreetingMiddleware The constructor of the type is injected with IGreeter object , And use it to realize InvokeAsync Method provides the corresponding greeting according to the current time , The latter will be the response content of the request .
1 public class GreetingMiddleware : IMiddleware
2 {
3 private readonly IGreeter _greeter;
4 public GreetingMiddleware(IGreeter greeter) => _greeter = greeter;
5
6 public Task InvokeAsync(HttpContext context, RequestDelegate next) => context.Response.WriteAsync(_greeter.Greet(DateTimeOffset.Now));
7 }
8
in the light of GreetingMiddleware The application of middleware is embodied in the following programs . As the code snippet shows , We call WebApplication Object's UseMiddleware<GreetingMiddleware> The extension method registers the middleware . Because strongly typed middleware instances are provided by dependency injection containers in real time when needed , So we must register it as a service in advance . The registered registration will eventually be added to WebApplicationBuilder Of Services Property returns IServiceCollection On the object , After we get this object, we call its AddSingleton< GreetingMiddleware > Method to register the middleware as “ Singleton services ”. Because middleware depends on IGreeter service , So we call AddSingleton<IGreeter, Greeter> The extension method registers the service .
1 using App;
2 var builder = WebApplication.CreateBuilder(args);
3 builder.Services
4 .AddSingleton<IGreeter, Greeter>()
5 .AddSingleton<GreetingMiddleware>();
6 var app = builder.Build();
7 app.UseMiddleware<GreetingMiddleware>();
8 app.Run();
After the program starts , The request for it will get a greeting generated according to the current time . Pictured 5 Shown , As the current time is 7 p.m , So the browser shows “Good evening!”.
chart 5 Customize the greetings returned by the middleware
[108] Define contract based Middleware types ( Constructor injection )
In fact, the middleware type does not have to implement an interface , Or inherit a base class , Define according to the established agreement . according to ASP.NET Core The agreement of , The middleware type needs to be defined as a public instance type ( Invalid static type ), Its constructor can inject any dependent service , But it must include a RequestDelegate Parameters of type , This parameter represents the pipeline built by subsequent middleware , Current middleware uses it to distribute requests to subsequent pipelines for further processing . The processing of requests is implemented in a named InvokeAsync perhaps Invoke The methods of , The return type of this method is Task, The first parameter is bound to the current HttpContext Context , therefore GreetingMiddleware The middleware type can be rewritten as follows .
1 public class GreetingMiddleware
2 {
3 private readonly IGreeter _greeter;
4 public GreetingMiddleware(RequestDelegate next, IGreeter greeter) => _greeter = greeter;
5 public Task InvokeAsync(HttpContext context) => context.Response.WriteAsync(_greeter.Greet(DateTimeOffset.Now));
6 }
Strongly typed middleware instances are provided in real time by the dependency injection container when processing requests , Middleware instances defined by agreement are different , When we registered the middleware, we created it by using the dependency injection container , So the former can adopt different life cycle patterns , The latter is always a singleton object . That's why , We don't need to register middleware as a service .
1 using App;
2 var builder = WebApplication.CreateBuilder(args);
3 builder.Services.AddSingleton<IGreeter, Greeter>();
4 var app = builder.Build();
5 app.UseMiddleware<GreetingMiddleware>();
6 app.Run();
[109] Define contract based Middleware types ( Methods to inject )
For middleware types defined by convention , Dependent services do not have to be injected into the constructor , They choose to inject directly into InvokeAsync perhaps Invoke In the method , So this one above GreetingMiddleware Middleware can also be defined in the following form . For middleware types defined by convention , Constructor injection and method injection are not equivalent , The difference between the two will be in 18 Chapter “ Application hosting ( Next )” Introduced in .
1 public class GreetingMiddleware
2 {
3 public GreetingMiddleware(RequestDelegate next){}
4 public Task InvokeAsync(HttpContext context, IGreeter greeter) => context.Response.WriteAsync(greeter.Greet(DateTimeOffset.Now));
5 }
[110] Configured applications
Development ASP.NET Core The application process will be widely used to configure (Configuration),ASP.NET Core A very flexible configuration framework is adopted , We can store data in any carrier as the configuration source . We can also convert the structured configuration into the corresponding options (Options) type , Use them in a strongly typed way . The system introduction for configuration options is placed on page 5 Chapter “ configuration option ( On )” And the 6 Chapter “ configuration option ( Next )” in , Let's start here “ preheating ” once . In the example shown earlier ,Greeter The greeting provided by type for the specified time is still in “ Hard encoding ” The way to provide , Now we choose to put them in the configuration file for easy adjustment . To do this, we add a file named “appsettings.json” Configuration file for , And define the three greetings in the following form JSON In file .
1 {
2 "greeting": {
3 "morning": "Good morning!",
4 "afternoon": "Good afternoon!",
5 "evening": "Good evening!"
6 }
7 }
ASP.NET Core The configuration in the application passes IConfiguration Objects represent , We can take the form of dependency injection “ free ” Use it more efficiently . For the demo program , We just need to make IConfiguration Object injected into Greeter In the constructor of type , Then call it. GetSection Method to get the configuration section that defines the above greeting (“greeting”). In the realization of Greet In the method , We use the specified Key(“morning”、“afternoon” and “evening”) Extract the corresponding greeting . Because the application will automatically load this named according to the Convention when it starts (“appsettings.json”) The configuration file , So don't make any changes in other parts of the demo program .
1 public class Greeter : IGreeter
2 {
3 private readonly IConfiguration _configuration;
4 public Greeter(IConfiguration configuration) => _configuration = configuration.GetSection("greeting");
5
6 public string Greet(DateTimeOffset time) => time.Hour switch
7 {
8 var h when h >= 5 && h < 12 => _configuration["morning"],
9 var h when h >= 12 && h < 17 => _configuration["afternoon"],
10 _ => _configuration["evening"],
11 };
12 }
[111]Options Application
As mentioned earlier , Transform the structured configuration into the corresponding type Options object , Using them in a strongly typed way is a more recommended programming pattern . For this purpose, we define the following for the three configured greetings GreetingOptions Configure option types .
1 public class GreetingOptions
2 {
3 public string Morning { get; set; } = default!;
4 public string Afternoon { get; set; } = default!;
5 public string Evening { get; set; } = default!;
6 }
although Options Objects cannot be injected directly in the form of dependent services , But it can be injected by IOptions<TOptions> Object to provide . This is shown in the following code snippet , We are Greeter The constructor of the type is injected with IOptions<GreetingOptions> object , And use it Value Properties get what we need GreetingOptions object . After having this object , Realized Greet Method only needs to get the corresponding greeting from the corresponding attribute .
1 public class Greeter : IGreeter
2 {
3 private readonly GreetingOptions _options;
4 public Greeter(IOptions<GreetingOptions> optionsAccessor) => _options = optionsAccessor.Value;
5
6 public string Greet(DateTimeOffset time) => time.Hour switch
7 {
8 var h when h >= 5 && h < 12 => _options.Morning,
9 var h when h >= 12 && h < 17 => _options.Afternoon,
10 _ => _options.Evening
11 };
12 }
because IOptions<GreetingOptions> The configuration options provided by the object cannot be made out of nothing ( It actually exists in the configuration ), We need to set the corresponding configuration section (“greeting”) Bound to the GreetingOptions On the object . This work actually belongs to the scope of service registration , Specifically, it can be called in the following form IServiceCollection Object's Configure<TOptions> Extend the method to complete . As the code snippet shows , Represents the overall configuration of the application IConfiguration Objects come from WebApplicationBuilder Of Configuration attribute .
1 using App;
2 var builder = WebApplication.CreateBuilder(args);
3 builder.Services
4 .AddSingleton<IGreeter, Greeter>()
5 .Configure<GreetingOptions>(builder.Configuration.GetSection("greeting"));
6 var app = builder.Build();
7 app.UseMiddleware<GreetingMiddleware>();
8 app.Run();
[112] The application of log
Diagnostic logs are essential for error correction .ASP.NET Core The diagnostic log framework adopted is powerful 、 Easy to use and flexible . In the program we demonstrated ,Greeter The type will return the corresponding greeting according to the specified time , Now let's record the time and the corresponding greetings in a log to see if they match . We have said before , Dependency injection is ASP.NET Core Apply the most basic programming mode . The functions we will cover ( Whether business-related or business-related ) To break up , Finally, the whole application is divided into parts by services with different granularity , The dependencies between services are directly solved by injection . We previously demonstrated the injection of configuration options , Next, we use it to record logs ILogger Objects are still obtained by injection . This is shown in the following code snippet , We are Greeter The constructor of the type is injected with ILogger<Greeter> object . In the realization of Greet In the method , We call the LogInformation The extension method records a Information Level log , The content of the log reflects the mapping relationship between time and greetings .
1 public class Greeter : IGreeter
2 {
3 private readonly GreetingOptions _options;
4 private readonly ILogger _logger;
5
6 public Greeter(IOptions<GreetingOptions> optionsAccessor, ILogger<Greeter> logger)
7 {
8 _options = optionsAccessor.Value;
9 _logger = logger;
10 }
11
12 public string Greet(DateTimeOffset time)
13 {
14 var message = time.Hour switch
15 {
16 var h when h >= 5 && h < 12 => _options.Morning,
17 var h when h >= 12 && h < 17 => _options.Afternoon,
18 _ => _options.Evening
19 };
20 _logger.LogInformation(message:"{time} => {message}",time, message);
21 return message;
22 }
23 }
use Minimal API Compiling ASP.NET Core The application will integrate diagnostic logs by default , So don't modify other parts of the whole demo program . When the modified application starts , For each request, it will be left in the log “ trace ”. Because the console is one of the log output channels enabled by default , The log content will be output directly to the console . chart 5 Shown is the console that launches the application in the form of a command line , The contents shown above are all output in the form of logs . In many system logs , We found that one was caused by Greeter Object output .
chart 5 Log output to the console
ASP.NET Core 6 Framework unveiling example demonstration [01]: More articles about programming experience
- [ASP.NET Core 3 The framework reveals ] Dependency injection [8]: The life cycle of the service instance
The life cycle determines IServiceProvider How do objects provide and release service instances . Although different versions of dependency injection frameworks adopt different implementations for lifecycle management of service instances , But in general, the principle is similar . In the dependency injection we provide ...
- [ASP.NET Core 3 The framework reveals ] Cross platform development experience : Docker
For one .NET Core Developer , You may not have used Docker, But you can't have never heard of it Docker.Docker yes Github One of the most popular open source projects on , It claims to be the cornerstone of all Cloud Applications , And upgrade the Internet ...
- [ASP.NET Core 3 The framework reveals ] Dependency injection : Inversion of control
ASP.NET Core The framework is based on some core infrastructure , These basic frameworks include dependency injection . file system . Configuration options and diagnostic logs etc . These frameworks are more than just supports ASP.NET Core Foundation of framework , We do the same when developing applications ...
- [ASP.NET Core 3 The framework reveals ] Dependency injection [5]: Using containers to provide services
It's no exaggeration to say , Whole ASP.NET Core The framework is based on the dependency injection framework .ASP.NET Core The application builds the pipeline at startup and the service objects used in processing each request from the dependency injection container . The dependency injection capacity ...
- [ASP.NET Core 3 The framework reveals ] file system [1]: In the abstract “ file system ”
ASP.NET Core application There are many scenarios for reading files , Such as configuration files . static state Web Resource file ( such as CSS.JavaScript And picture files ) as well as MVC Applied View file , Even embedded resource files compiled directly into the assembly ...
- [ASP.NET Core 3 The framework reveals ] file system [2]: overall design
stay < In the abstract " file system "> in , We have made a preliminary experience of file system from the perspective of programming through several simple examples , Next, we continue to understand it from the perspective of design . This abstract file system is organized in the form of directories ...
- [ASP.NET Core 3 The framework reveals ] To configure [1]: Read configuration data [ Part 1 ]
mention " To configure " Two words , I think most of .NET Two special files will come to mind immediately , That's what we're all familiar with app.config and web.config, Over the years, we've been used to structuring ...
- [ASP.NET Core 3 The framework reveals ] To configure [2]: Read configuration data [ The next part ]
[ Next chapter ] mention “ To configure ” Two words , I think most of .NET Two special files will come to mind immediately , That's what we're all familiar with app.config and web.config, Over the years, we've been used to defining structured configurations ...
- [ASP.NET Core 3 The framework reveals ] To configure [3]: Overall design of configuration model
stay < Read configuration data >([ Part 1 ],[ The next part ]) In the previous section , We demonstrate several typical configuration reading methods through examples , Next, we rewrite the cognitive configuration model from the design dimension . The programming model of configuration involves three core objects , Through three separate ...
- [ASP.NET Core 3 The framework reveals ] To configure [7]: Diversified configuration sources [ medium-length ]
Physical files are the most commonly used primitive configuration carriers , And the best configuration file format mainly has three kinds , They are JSON.XML and INI, The corresponding configuration source types are JsonConfigurationSource.XmlConfigura ...
Random recommendation
- win10 Common help
Add self start item : C:\ProgramData\Microsoft\Windows\Start Menu\Programs\StartUp shell:startup win10 Find the picture viewer : Win ...
- Office2010 And vs2008 A series of problems caused by incompatibility (vs The design view cannot be opened , Can't start Asp.Net Development Server)
vs2008 open aspx Solution of interface crash in file design One . And then one day , In the use of vs2008 When switching from source view to design view , The interface appears fake death , It is invalid after reinstallation . I search the reason from the Internet , I found that many friends have similar problems , But the solution ...
- 【 Work notes 】BAT Batch learning notes and examples
BAT Batch learning notes One . The definition of : Batch file is a set of commands in a certain order into an executable text file , Its extension is BAT perhaps CMD, These commands are collectively referred to as batch commands . Two . Common batch instructions : Command list : 1.RE ...
- echart Use of pie chart , Kill time .
New company , Just a few days , It's OK to be idle , The leader asked me to do some trivial work , Optimize report statistics !!! Used to flash It's done , Now it's going to be echart Realization . ok , I haven't used it before , With a learning attitude , Studied under . Write something to pass the time , Can help you in need ...
- Case learning
bad case: <?php foreach($user_detail AS $val) { if(!empty($val->portrait)) { // Let's assume that this cycle has never reached $ ...
- Prime Palindromes Prime Palindromes
Title Description because 151 It is both a prime number and a palindrome number ( From left to right is the same as from right to left ), therefore 151 Is palindrome prime number . Write a program to find out the scope [a,b](5 <= a < b <= 100,000 ...
- City string ---- Turn array ( Add space ---preg_split) Regular split string --> Array
Regular With Slash start Slash end Slash Surrounded / / Letter The backslash escape \s space Match spaces Multiple spaces [ \s ]+ brackets Surrounded public function ...
- openstack controller ha Test environment construction record ( Ten )—— To configure neutron( The control node )
establish neutron user :mysql -u root -p CREATE DATABASE neutron;GRANT ALL PRIVILEGES ON neutron.* TO 'neutron'@ ...
- Flex in TitleWindow Pass value
Flex in TitleWindow Pass value 1. Design thinking (1) Create a new one DataGrid, Add three buttons to the last column : newly added . Modification and deletion : (2) Click the new button , You can add a new row to the table : (3) single click " modify ...
- 1.let Command summary
1.let The usage is similar to var, however let Only valid in the code block { let a = 10; var b = 1; } a // ReferenceError: a is not defined. b // ...