net core 3.1 知识累积

执行顺序

Host.CreateDefaultBuilder(args)

        //     • set the Microsoft.Extensions.Hosting.IHostEnvironment.ContentRootPath to the
        //     result of System.IO.Directory.GetCurrentDirectory
        //     • load host Microsoft.Extensions.Configuration.IConfiguration from "DOTNET_"
        //     prefixed environment variables
        //     • load host Microsoft.Extensions.Configuration.IConfiguration from supplied command
        //     line args
        //     • load app Microsoft.Extensions.Configuration.IConfiguration from 'appsettings.json'
        //     and 'appsettings.[Microsoft.Extensions.Hosting.IHostEnvironment.EnvironmentName].json'
        //     • load app Microsoft.Extensions.Configuration.IConfiguration from User Secrets
        //     when Microsoft.Extensions.Hosting.IHostEnvironment.EnvironmentName is 'Development'
        //     using the entry assembly
        //     • load app Microsoft.Extensions.Configuration.IConfiguration from environment
        //     variables
        //     • load app Microsoft.Extensions.Configuration.IConfiguration from supplied command
        //     line args
        //     • configure the Microsoft.Extensions.Logging.ILoggerFactory to log to the console,
        //     debug, and event source output
        //     • enables scope validation on the dependency injection container when Microsoft.Extensions.Hosting.IHostEnvironment.EnvironmentName
        //     is 'Development'

部署发布

IIS发布篇

模块 --> AspNetCoreModuleV2

为什么不发布就不能部署? -- 直接指向项目,会失败

命令行篇

1.在bin目录直接运行

dotnet Study.NetCore31.practical.dll --urls=http://*:3001

样式问题:

//1.把wwwroot拷贝过去
//2.添加默认路径
app.UseStaticFiles( new StaticFileOptions()
             {
                 FileProvider =new PhysicalFileProvider(Path.Combine(Directory.GetCurrentDirectory(),"wwwroot"))
             });

AOP注册

新建一个 Filter\CustomExceptionFilterAttribute.cs

public class CustomExceptionFilterAttribute : ExceptionFilterAttribute
    {
        public override void OnException(ExceptionContext context)
        {
            Console.WriteLine("aaaa");
            //base.OnException(context);
        }
    }

1.全局注册

在有错的地方就会执行

services.AddControllersWithViews(option =>
            {
                //全局注册filter
                option.Filters.Add(typeof(CustomExceptionFilterAttribute));
            });

2.ServiceFilter

Startup.cs

services.AddTransient(typeof(CustomExceptionFilterAttribute));

HomeController.cs

//放在控制器
	[ServiceFilter(typeof(CustomExceptionFilterAttribute))]
    public class HomeController : Controller
 	{
		...
		
 		public IActionResult Privacy()
        {
            throw new Exception("12");
            return View();
        }
	 }

3.TypeFilter

4.IFilterFactory

StartUp 启动顺序

IOC的注册方法

先来自定义OrderService

	public interface IOrderService { }
    public class OrderService : IOrderService
    {
    }

其他类似,下面是一些使用方法

  			#region 注册不同声明周期的服务
            services.AddSingleton<IMySingletonService, MySingletonService>();
            services.AddTransient<IMyTransientService, MyTransientService>();
            services.AddScoped<IMyScopeService, MyScopeService>();
            #endregion

            #region 花式注册

            services.AddSingleton<IOrderService>(new OrderService());
            //可以组装复杂注册
            services.AddSingleton<IOrderService>(serviceProvider =>
            {
                serviceProvider.GetService<IOrderService>();
                return new OrderService();
            });
            #endregion

            #region 尝试注册
            //如果注册过 IMySingletonService,这里是不会成功的
            services.TryAddSingleton<IOrderService, OrderService>();

            //如果注册过 IMySingletonService,这里是不会成功的,但是如果实例不同,就会注册成功
            services.TryAddEnumerable(ServiceDescriptor.Singleton<IOrderService, OrderServiceEx>());
            #endregion

            #region 移除和替换
            services.RemoveAll<IOrderService>();
            services.Replace(ServiceDescriptor.Singleton<IOrderService, OrderServiceEx>());
            #endregion

比较特殊点的是泛型模版注册

    public interface IGenericService<T> { }
    public class GenericService<T> : IGenericService<T>
    {
        public T Data { get; set; }

        public GenericService(T data)
        {
            this.Data = data;
        }
    }

这里像开始那样写就不行了,必须像这样

            #region 泛型模版
            //services.AddSingleton<IGenericService<>,GenericService<>(); //失败
            services.AddSingleton(typeof(IGenericService<>), typeof(GenericService<>));
            #endregion

配置框架

        static void Main(string[] args)
        {
            IConfigurationBuilder builder = new ConfigurationBuilder();
            builder.AddInMemoryCollection(new Dictionary<string, string>
        {
           {"MyKey", "Dictionary MyKey Value"},
           {"Position:Title", "Dictionary_Title"},
           {"Position:Name", "Dictionary_Name" },
           {"Logging:LogLevel:Default", "Warning"}
        });

            //IConfigurationRoot 配置结构的根
            IConfigurationRoot configurationRoot = builder.Build();
            Console.WriteLine(configurationRoot["MyKey"]); //Dictionary MyKey Value
            Console.WriteLine(configurationRoot["Position:Title"]); //Dictionary_Name

            IConfiguration config = configurationRoot;
            IConfigurationSection section = config.GetSection("Logging");
            Console.WriteLine(section["LogLevel:Default"]); //Warning
        }

命令行

https://docs.microsoft.com/zh-cn/aspnet/core/fundamentals/configuration/?view=aspnetcore-3.1#command-line

使用默认配置,CommandLineConfigurationProvider 会从以下配置源后的命令行参数键值对中加载配置:

支持的格式

  • 无前缀的key=value模式
  • 双中横线模式--key=value 或--key value
  • 正斜杠模式/key=value或/key value

备注: 等号分隔符和空格分隔符不能混用

例子
Properties\launchSettings.json

{
  "profiles": {
    "CommandDemo": {
      "commandName": "Project",
      "commandLineArgs": "help=F9 --CommandLineKey2=value2 /CommandLineKey3=value3 "
      //"commandLineArgs": "help=F9 --CommandLineKey2=value2 /CommandLineKey3=value3 -k1=k3"
    }
  }
}

Program.cs

        static void Main(string[] args)
        {
            IConfigurationBuilder builder = new ConfigurationBuilder();
            builder.AddCommandLine(args);

            #region
            //var mapper = new Dictionary<string, string>() { { "-k1", "help" } };
            //builder.AddCommandLine(args, mapper);
            #endregion

            var configurationRoot = builder.Build();
            Console.WriteLine($"help:{configurationRoot["help"]}");
            Console.WriteLine($"CommandLineKey2:{configurationRoot["CommandLineKey2"]}");
            Console.WriteLine($"CommandLineKey3:{configurationRoot["CommandLineKey3"]}");
            Console.ReadKey();
        }
			//help:F9
			//CommandLineKey2:value2
			//CommandLineKey3:value3

命令替换模式

  • 必须以单划线(-)或双划线(--)开头
  • 映射字典不能包含重复Key
    例子
    Properties\launchSettings.json
{
  "profiles": {
    "CommandDemo": {
      "commandName": "Project",
      //"commandLineArgs": "help=F9 --CommandLineKey2=value2 /CommandLineKey3=value3 "
      "commandLineArgs": "help=F9 --CommandLineKey2=value2 /CommandLineKey3=value3 -k1=k3"
    }
  }
}

Program.cs

        static void Main(string[] args)
        {
            IConfigurationBuilder builder = new ConfigurationBuilder();
            //builder.AddCommandLine(args);

            #region 命令替换
            var mapper = new Dictionary<string, string>() { { "-k1", "help" } };
            builder.AddCommandLine(args, mapper);
            #endregion

            var configurationRoot = builder.Build();
            Console.WriteLine($"help:{configurationRoot["help"]}");
            Console.WriteLine($"CommandLineKey2:{configurationRoot["CommandLineKey2"]}");
            Console.WriteLine($"CommandLineKey3:{configurationRoot["CommandLineKey3"]}");
            Console.ReadKey();
        }
			//help:k3
			//CommandLineKey2:value2
			//CommandLineKey3:value3

总结:类似于 -h--help 的简写

-h|--help         显示命令行帮助。

环境变量

https://docs.microsoft.com/zh-cn/aspnet/core/fundamentals/configuration/?view=aspnetcore-3.1#environment-variables

EnvironmentVariablesConfigurationProvider 会在读取 appsettings.json、appsettings.Environment.json 和机密管理器后从环境变量键值对加载配置 。

所有平台上的环境变量分层键都不支持 : 分隔符。
__(双下划线)代替:

  • 受所有平台支持。 例如,Bash 不支持 : 分隔符,但支持 __。
  • 自动替换为 :

分层键

            #region 环境变量
            IConfigurationBuilder builder = new ConfigurationBuilder();
            builder.AddEnvironmentVariables();

            var configurationRoot = builder.Build();
            Console.WriteLine($"STAGING:{configurationRoot["STAGING"]}");

            //分层键
            var production = configurationRoot.GetSection("Production");
            Console.WriteLine($"hotfix:{production["hotfix"]}");
            Console.WriteLine($"hotfix:{production["hotfix:vn"]}");
            #endregion

前缀过滤

            //前缀过滤
            builder.AddEnvironmentVariables("STAGING_");
            var configurationRoot = builder.Build();
            Console.WriteLine($"STAGING:{configurationRoot["Brance2"]}"); //JAP

路由

路由方式

  • 路由模版的方式(MVC)
		public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllers();
            services.AddRouting();
            //core 3.1 必须设置 option.EnableEndpointRouting = false
            services.AddMvc(option => option.EnableEndpointRouting = false);
            ...
        }

		public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            app.UseMvc(route =>
            {
                route.MapRoute("default", template: "api/{controller}/{action}");
            });
        }
	//[Route("api/Authors")]
    //[ApiController]
    public class AuthorController : ControllerBase
    {
        public IAuthorRepository AuthorRepository { get; }
        public AuthorController(IAuthorRepository authorRepository)
        {
            AuthorRepository = authorRepository;
        }
		
        //https://localhost:5001/api/Author/GetAuthors
        [HttpGet]
        public ActionResult<List<AuthorDto>> GetAuthors()
        {
            return AuthorRepository.GetAuthors().ToList();
        }
		
        //https://localhost:5001/api/Author/GetAuthor?authorId=72D5B5F5-3008-49B7-B0D6-CC337F1A3330
        [HttpGet]
        public ActionResult<AuthorDto> GetAuthor(Guid authorId)
        {
            var author = AuthorRepository.GetAuthor(authorId);

            if (author == null)
            {
                return NotFound();
            }
            else
            {
                return author;
            }
        }
    }
  • RouteAttribute 方式 (WebApi)
app.UseEndpoints(endpoints =>
{
    //使用 RouteAttribute
    endpoints.MapControllers();
});
	[Route("api/Authors")]
    [ApiController]
    public class AuthorController : ControllerBase
    {
        public IAuthorRepository AuthorRepository { get; }
        public AuthorController(IAuthorRepository authorRepository)
        {
            AuthorRepository = authorRepository;
        }

        //https://localhost:5001/api/Authors
        [HttpGet]
        public ActionResult<List<AuthorDto>> GetAuthors()
        {
            return AuthorRepository.GetAuthors().ToList();
        }
		
        //https://localhost:5001/api/Authors/72D5B5F5-3008-49B7-B0D6-CC337F1A3330
        [HttpGet("{authorId}")]
        public ActionResult<AuthorDto> GetAuthor(Guid authorId)
        {
            var author = AuthorRepository.GetAuthor(authorId);

            if (author == null)
            {
                return NotFound();
            }
            else
            {
                return author;
            }
        }
    }

路由约束

  • 类型约束
  • 范围约束
  • 正则表达式
  • 是否必选
  • 自定义 IRouteConstraint

URL生成

  • LinkGenerator
  • IUrlHelper
posted @ 2020-05-03 15:47  【唐】三三  阅读(552)  评论(0编辑  收藏  举报