.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<Startup>();
            });
}

可以看到,程序先创建了个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<ApplicationDbContext>(option => option.UseSqlServer(conn));

        services.AddIdentity<Useraccount, IdentityRole>(
            options => options.SignIn.RequireConfirmedAccount = true
        ).AddEntityFrameworkStores<ApplicationDbContext>();
        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<int> _list;
      	public void Change()
      	{
      		_list.Count;
      	}
      }
    

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

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

      public class MyClass
      {
      	IList<int> _list;
      	public void Change(IList<int> 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<Useraccount> _userManager;
    	private readonly SignInManager<Useraccount> _signInManager;
    	private readonly IAccountProfileService _profileService1;
	private readonly IAccountProfileService _profileService2;
		
    	public AccountController(UserManager<Useraccount> userManager,SignInManager<Useraccount> 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;//设置
      }
      );


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM