[AspNetCore2.x]Aspnetcore中理论知识
2019-03-31 本文已影响0人
谁有羊毛
理论原理
一、依赖注入于StartUp.cs类中
asp.net core毫无疑问是使用的构造子注入方式,没有使用配置文件而是采用了一个代码配置的方式。都注入到services中,对于注入方式
// AddTransient 方法将一个类型注册为 Transient 生命周期。因此,每一次你从依赖注入中请求一个 MyTransientClass 实例,你都会得到一个全新实例化的实例。请求10次,就得到10个不同的实例。
service.AddTransient<MyTransientClass>();
// AddSingleton 方法将一个类型注册为 Singleton 生命周期。单体大家都懂,就是无论请求多少次,你从依赖注入都会得到同一个 MySingletonClass 实例。请求10次,得到的却是同一个实例。
service.AddSingleton<MySingletonClass>();
// AddScoped 方法将一个类型注册为 Scoped 生命周期。这个生命周期比较特别。如果你的程序里创建了若干个 "Scope",依赖注入会确保在同一个 Scope 里,你将得到同一个 MyScopedClass 实例,而不同 Scope 里的 MyScopedClass 实例是不同的
// 假设你有3个Scope,每个Scope里请求10次,那么你将得到3个不同的 MyScopedClass 实例。其中每个 Scope 里一个。
// 至于 Scope 到底是什么含义,这就因程序而异了。比如在 ASP.NET Core 里,一个Scope意味着一次浏览器请求往返。而在我们的示例程序里,一个Scope代表一个线程内部。
service.AddScoped<MyScopedClass>();
以上3个生命周期类型基本上涵盖了所有可能的场景:
- 每次都要新实例。
- 永远都只需要同一个实例。
- 在一个范围之内只需要同一个实例,但是不同范围之内的实例要不同。
取实例的话是借助接口来取IService
DI示例
public void ConfigureServices (IServiceCollection services) {
services.AddDbContext<DataDbContext> (options => options.UseSqlite (Configuration.GetConnectionString ("DefaultConnection")));
services.AddTransient<IOperationTransient, Model.Operation> ();
services.AddScoped<IOperationScoped, Model.Operation> ();
services.AddSingleton<IOperationSingleton, Model.Operation> ();
services.AddSingleton<IOperationSingletonInstance> (new Model.Operation (Guid.Empty));
}
二、中间件的使用
中间件是位于请求管道的,对请求进行处理的类
- app.Use 这个表示有两种可能。
- 正常的调用next方法,会把请求传到下一个中间件中
- 不调用next,会终止请求
app.UseMvc ();
- app.Run 一个约定,暴露其运行的方法,不调用next也会终止请求
app.Run (async context => {
await context.Response.Body.WriteAsync(System.Text.Encoding.Default.GetBytes ("HI world"),0,4);});
if (env.IsDevelopment ()) {
app.UseDeveloperExceptionPage ();
}
- app.Map 分支请求:Map可以分支请求。比如不进行验证也可以请求其他资源:
app.Map ("/map_o", (_app) => {
_app.Run (async context => {
await context.Response.Body.WriteAsync (System.Text.Encoding.Default.GetBytes ("HI world"),0,7);});
});
app.UseAuthentication()
- app.MapWhen : eg:当分支请求的参数中包含 branch时,进入此中间件
app.MapWhen (context => context.Request.Query.ContainsKey ("branch"),
(_app) => {
_app.Run (async context => {
var branchVer = context.Request.Query["branch"];
string responseStr = $"Branch used = {branchVer}";
await context.Response.Body.WriteAsync (System.Text.Encoding.Default.GetBytes (responseStr), 0, responseStr.Length);
});
})
- 编写自己的中间件
- (1) 创建一个中间件实际内容的类
using Microsoft.AspNetCore.Http;
using System.Globalization;
using System.Threading.Tasks;
namespace Culture
{
public class RequestCultureMiddleware
{
private readonly RequestDelegate _next;
public RequestCultureMiddleware(RequestDelegate next)
{
_next = next;
}
public Task Invoke(HttpContext context)
{
var cultureQuery = context.Request.Query["culture"];
if (!string.IsNullOrWhiteSpace(cultureQuery))
{
var culture = new CultureInfo(cultureQuery);
CultureInfo.CurrentCulture = culture;
CultureInfo.CurrentUICulture = culture;
}
// Call the next delegate/middleware in the pipeline
return this._next(context);
}
}
}
- (2)、使用IApplicationBuilder公开中间件:
using Microsoft.AspNetCore.Builder;
namespace Culture
{
public static class RequestCultureMiddlewareExtensions
{
public static IApplicationBuilder UseRequestCulture(
this IApplicationBuilder builder)
{
return builder.UseMiddleware<RequestCultureMiddleware>();
}
}
}
- (3)、调用中间件:
public class Startup
{
public void Configure(IApplicationBuilder app)
{
app.UseRequestCulture();
}
}