.netcore

.NET与.NETCore

在5.0版本之前,.NET代表.NETFramework,在5.O版本之后Framework被抛弃,与Core合并为.NET5.0

.NETCore从哪开始

毫无疑问,C#程序都是以Program.cs文件中的Main方法开始。

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();
});
}
可以看到,程序先创建了个IHostBuilder,将args参数传入Host.CreateDefaultBuilder方法中。在此方法中才调用大名鼎鼎的Startup类。
可以不使用Startup类,其作用只是配置host,甚至可以根据控制台指令执行不同的TStartup类。
自定义TStartup:(TStartup可以是任意类,没有接口限制。)

public class ClassOne
{
public ClassOne(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
public void ConfigureServices(IServiceCollection services)
{
var conn = Configuration["ConnectionString:DefaultConn"];
services.AddDbContext(option => option.UseSqlServer(conn));

services.AddIdentity<Useraccount, IdentityRole>(
options => options.SignIn.RequireConfirmedAccount = true
).AddEntityFrameworkStores();
services.AddControllersWithViews(
config =>
{
var policy = new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.Build();
config.Filters.Add(new AuthorizeFilter(policy));
}
);
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.UseAuthentication();

app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
});
}
}
必须要的几点:

1.带IConfiguration参数的构造函数。
2.public IConfiguration Configuration { get; }
3.public void ConfigureServices(IServiceCollection services)因为要使用MVC必须先注册服务。
4.public void Configure(IApplicationBuilder app, IWebHostEnvironment env)参数自己看着加,IApplicationBuilder是设置中间件,IWebHostEnvironment是文件环境(可以取根目录等等)。

服务的依赖注入

依赖注入DI和控制反转IoC

  • 依赖注入
    首先理解依赖:

    public class MyClass
    {
    List _list;
    public void Change()
    {
    _list.Count;
    }
    }
    在MyClass中有一个_list属性,就说明其存在一个依赖。并且可以发现_list没有初始化,并且Change方法希望访问其Count参数。按上述代码是不会编译通过的。所以需要从外部注入_list实例。这就是依赖注入的含义。

    public class MyClass
    {
    List _list;
    public void Change(List list)
    {
    _list.Count;
    }
    }

  • 控制反转
    学习了接口之后,我们得以充分了解面向对象的特点——多态。多态的特性是实现控制反转的基础。在没有多态之前,每个函数都必须接受精确的、数量相同的参数。这说明控制权掌握在函数。将参数类型调整为基类(如Object)时,函数可接受范围变大,函数是处于被动接受的状态——给什么参数都要收。这就叫控制反转
    但是有时候会发现使用Object太广泛了,所以接口的作用就凸显出来了。在C#中,接口就是对类的特点的集合。例如有许许多多不同种类的鸟,但是他们都有共同的特点——会飞、长有两只翅膀。那么就可以使用IBird接口抽象形容它。使用接口做参数相对于用Object同样是控制反转,只是范围缩小了。

    public class MyClass
    {
    IList _list;
    public void Change(IList list)
    {
    _list.Count;
    }
    }
    回到Core中

    services.AddScoped<IAccountProfileService, AccountProfileService>();
    注入方法与只用接口注入不同。可以看到ConfigureServices(IServiceCollection services)的参数是一个service集合,服务就是注入到这个动态集合里。AddScoped<T1,T2>()方法中T2是服务类,T1是服务接口。所以每一个需要注入的服务都要有一个接口。

  • 使用Add方法注入服务后怎么实例化服务?
    有三种服务类型

1.Transient:每一次GetService都会创建一个新的实例。
什么时候是getservice呢?

public class AccountController : Controller
{
private readonly UserManager _userManager;
private readonly SignInManager _signInManager;
private readonly IAccountProfileService _profileService1;
private readonly IAccountProfileService _profileService2;

public AccountController(UserManager userManager,SignInManager siginManager
, IAccountProfileService profileService1,IAccountProfileService profileService2)
{
_userManager = userManager;
_signInManager = siginManager;
_profileService1 = profileService1;
_profileService2 = profileService2;
}
}
假设用户发送一个请求,AccountController响应了。通过构造器生成两个服务,如果是Transient那么两个服务不同。如果是Scoped,在下一次http服务发送来之前两个服务相同。Singleton都是同一服务。
2.Scoped:在同一个Scope内只初始化一个实例 。
3.Singleton:整个应用程序生命周期内只创建一个实例。

Core的优点在哪

可扩展性强:framework程序开始时选框架,之后添加框架麻烦。core采用服务注入的方式添加框架,灵活性更强。服务之间相互独立,减少耦合。

中间件

https://www.cnblogs.com/liujiabing/p/11498163.html

  • 什么是中间件:
    出于安全性考虑,前端发送来的请求都不能直接输入后端。需要管道对信息预处理,管道中的组件就是中间件。
    主要功能:信息安全、对数据预处理、调度分配

  • 中间件执行顺序:
    image

  • .netcore终端中间件:

  1. Run

    app.Run(async (context) =>
    {
    await context.Response.WriteAsync("Hello World!");
    });
    执行该函数后会直接跳到管道末尾,后续中间件不会执行。

  2. Map

    app.Map("map1", app =>
    {
    app.Run(async (context) =>
    {
    await context.Response.WriteAsync("Hello World!");
    });
    });
    第一个参数:匹配条件是HttpContext.Request.Path和预设值。
    第二个参数:自定义管道。
    可以根据这个函数设计多个管道分支。

  3. MapWhen
    map加约束版本

    app.MapWhen(context =>
    context.Request.Query.ContainsKey("nihao"), app =>
    {
    app.Run(async (context) =>
    {
    await context.Response.WriteAsync("Hello World!");
    });
    }
    );

  • 路径设置:
    .netcore中MVC会默认设置有终端模式:
    设置默认路由,就是设置终端路由。

    app.UseEndpoints(endpoints =>
    {
    endpoints.MapControllerRoute(
    name: "default",
    pattern: "{controller=Home}/{action=Index}/{id?}");
    });

    老方法

    app.UseMvc(routes =>
    {
    routes.MapRoute(
    name: "default",
    template: "{controller=Home}/{action=Index}/{id?}");
    });
    老方法需要吧mvc设置为无终端模式。

    services.AddControllersWithViews(
    config =>
    {
    var policy = new AuthorizationPolicyBuilder()
    .RequireAuthenticatedUser()
    .Build();
    config.Filters.Add(new AuthorizeFilter(policy));
    config.EnableEndpointRouting = false;//设置
    }
    );

posted @ 2021-09-29 17:48  none323  阅读(419)  评论(0)    收藏  举报