当前位置: 首页 > news >正文

免费的黄冈网站有哪些平台?成全视频免费观看在线看收索

免费的黄冈网站有哪些平台?,成全视频免费观看在线看收索,wordpress主题无法创建目录,天元建设集团有限公司第十一建筑工程分公司我的博客换新家啦#xff0c;新的地址为#xff1a;https://clrdaily.com :-D今天我们来一起思考一下如何在不同的环境应用不同的配置。这里的配置不仅仅指 IConfiguration 还包含 IWebHostBuilder 的创建过程和 Startup 的初始化过程。0 太长不读环境造成的差异在架构中基本… 我的博客换新家啦新的地址为https://clrdaily.com :-D今天我们来一起思考一下如何在不同的环境应用不同的配置。这里的配置不仅仅指 IConfiguration 还包含 IWebHostBuilder 的创建过程和 Startup 的初始化过程。0 太长不读环境造成的差异在架构中基本体现在 Infrastructure 中的各个 Adapter 中。而不应当入侵应用程序内部在 ASP.NET Core 中我们需要考虑如何将这些 Adapter一放在 service collection 中 二可选添加到 pipeline 中。ASP.NET Core 默认提供了一系列手段来判断当前的环境只不过这些手段的设计奇怪且不完整。IWebHostBuilder 的配制方法大多和环境相关但 UseSetting 和环境无关。我们应当应用开闭原则将相同环境的配置聚合起来不同环境的配置进行统一抽象。方便维护和扩展。当我们进行设计的时候需要注意不要将思路局限在 Framework 的设计上而应当切实考虑我们真正希望解决的问题。1 架构层面的思考Web Service 的开发和部署过程会涉及若干环境。总的来说可以分为开发环境和部署环境。而部署环境往往又分为 QA、Stage 和 Production 等。对于不同的环境应用程序可能需要应用不同的配置或实现。还是回到架构的层面上如下图那么这种不同应该体现在架构的哪一个层面上呢应当让这些不同体现在 Infrastructure 的那些 Adapters 上。因为 Adapter 是其中直接和环境相关的部分。用一个典型的例子来表示。假定一个注册用户 Account 的业务。在 Application Service 层面我们提供了如下的接口public class AccountRegistrationService {    public AccountRegistrationResult Register(AccountRegistrationRequest request) {        Account account  this.repository.CreateDetached();        // initialize account from request        account.Save();        return AccountRegistrationResult.Create(account);    }}在 Domain 层面我们有代表领域对象 Account 的类型 Account。Account 类型的 Save() 方法可以保存账户信息其中的实现类似public class Account {    ...    public void Save() {        this.repository.Save(this);    }}而其中的 repository 则依赖 UnitOfWork 而 UnitOfWork 则可能依赖于具体的持久化实现或者依赖于其他远程服务public class AccountRepository {    readonly IUnitOfWork session;    public Account CreateDetached() {        return new Account(this);    }    public void Save(Account account) {        this.session.RegisterNew(account);    }}在这个例子中AccountService 属于 Application Service 层面Account 和 AccountRepository 则属于 Domain 层面。这两层的依赖关系是 Application Service 依赖于 Domain。而 Domain 中的 UnitOfWork 则是一个接口。假设我们需要将数据写入数据库。则这个接口的实现需要持久化的支持例如它需要使用特定的 IDbConnection Adapter。即 IUnitOfWork 的实现位于 Infrastructure 层并在 Infrastructure 层调用 Adapter 向 DB 中写入信息。而对于不同的环境则可以使用不同的实现例如对于运行单元测试的环境我们不妨叫她 Test 环境。这个 DB 很有可能是一个 in memory 的 SQLite 数据库。而在生产环境则是 MySQL 的集群。应用程序的内部逻辑最终全部依赖与特定的抽象或接口。它们全部严密的包裹在 Infrastructure 之中并和外部环境完全隔离。而 Infrastructure 中的 Adapter 则负责联系外部环境。综上所述环境相关的变化应当全部封闭在 Infrastructure 中。2 ASP.NET Core 中的对应关系ASP.NET Core 应用程序中的组件的初始化由两个部分构成第一个部分就是将组件中的类型添加到依赖注入的 IServiceCollection 实例中以便进行创建第二个部分可选即将组件通过 IApplicationBuilder 添加到应用程序的处理流水线中。我们一个一个来思考。2.1 依赖注入ASP.NET Core Web Application 中用依赖注入来决定某种抽象的实现类型。但需要指出的是 ASP.NET 应用程序的依赖注入是分两个阶段进行的。我们将在另外一篇中介绍简单来说 ServiceCollection 的构建分为两个部分为了构建宿主环境而添加的类型Infrastructure 层为了应用程序本身而添加的 Framework例如 MvC和各种业务类型。Infrastructure 层Application Domain 层。而和环境相关的部分主要位于 “为了构建宿主环境而添加的类型” 中。这一部分的代码属于在 IStartup 初始化之前的 WebHostBuilder 构建代码中。一般来说我们习惯于将 UseStartup 调用放在 IWebHostBuilder 实例创建的最后那么也就是 UseStartup 之前的代码public static IWebHostBuilder CreateWebHostBuilder(string[] args){    return new WebHostBuilder()        .UseKestrel()        .ConfigureLogging(...)        //        // The configurations before UseStartup are environment specific        //        .UseStartupStartup();}2.2 流水线在流水线配置中主要考虑的是 Web 输入输出上的的变化。例如 Production 环境需要配置 SSL消除敏感 Header消除详细的 Error Information 等等。将组件配置到应用程序的流水线的操作是在 IStartup 接口的实现中进行的。定义 IStartup 接口实现的方式大体有两种第一种是调用 WebHostBuilderExtensions.Configure 方法另一种是使用 WebHostBuilderExtensions.UseStartup 方法。不论使用何种方式最终都会归结到对 IApplicationBuilder 的操作public void Configure(IApplicationBuilder app) {    // building pipeline}在这个时候宿主初始化相关的类型已经全部可以使用了。因此取用环境相关的信息环境类型配置等就更方便了。3 落地ASP.NET Core 对这个环节的设计很奇怪。一方面它提供了非常底层的基于 IHostingEnvironment.EnvironmentName 的值来进行环境区分的方法。例如官方范例中往往会使用如下的代码new WebHostBuilder()    .UseKestrel()    .ConfigureLogging((context, logBuilder)  {        if (context.HostingEnvironment.IsDevelopment()) {            ...        }        else if (context.HostingEnvironment.IsProduction()) {            ...        }        else {            ...        }    })    ...而另一方面却又在 Startup 上设计了命名的 Convension。例如class DevelopmentStartup {}     // for Developmentclass ProductionStartup {}      // for Productionclass Startup {}                // fallback...webHostBuilder.UseStartup(assemblyName);又例如class Startup  {    public void ConfigureServices(IServiceCollection services) { }    public void ConfigureStagingServices(IServiceCollection services) { }    public void Configure(IApplicationBuilder app, IHostingEnvironment env) { }    public void ConfigureStaging(IApplicationBuilder app, IHostingEnvironment env) { }}这些设计差异很大且每一个都不彻底。而在实际项目中环境属于一个扩展点而每一套环境的各项配置应当是内聚的。因此上述几种方式或多或少会增加维护上的成本。而较好的设计应当针对如下三个问题能够立刻说出我的系统支持几种环境每一种环境的各种类型的配置例如配置源、日志记录、HTTP Client、数据库是什么样子的有什么差异能不能用两步添加一个新的环境第一一次性创建一个新环境的所有配置第二将这个环境纳入到系统初始化过程中。为了达到这个要求需要考虑统一的实现手段。3.1 在 WebHost 开始构建之前我们并不能确定环境信息一个最简单的想法就是根据不同的环境采取两种完全不同的 WebHostBuilder 配置流程。例如WebHostBuilder builder  new WebHostBuilderFactory().Create(env.EnvironmentName);遗憾的是这种设计本身是有问题的。首先若干环节都可以影响环境的最终确定包括当前 Session 的 ASPNETCORE_ENVIRONMENT 的值请参见 https://github.com/aspnet/AspNetCore/blob/master/src/Hosting/Hosting/src/WebHostBuilder.cs#L44Properties/launchSettings.json 中选定 Profile 中 ASPNETCORE_ENVIRONMENT 的值如果用 dotnet run 命令执行的话WebHostBuilder.UseEnvironment(name) 的参数值WebHostBuilder.UseSetting(key, value) 当 key 为 WebHostDefaults.EnvironmentKey 时的值。若 Host 在 IIS 中则 web.config 中关于 environmentVariable 的设置。因此只有在 WebHostBuilder 开始 Build 时我们才可以最终确定环境名称。3.2 UseSetting 并不是环境相关的另一种方案是包装 IWebHostBuilder 使其能够依据环境做出相应的 Dispatch。例如abstract class EnvironmentAwareWebHostBuilder : IWebHostBuilder {    IWebHostBuilder UnderlyingBuilder { get; }    protected abstract bool IsSupported(IHostingEnvironment hostingEnvironment);    protected EnvironmentAwareWebHostBuilder(IWebHostBuilder underlyingBuilder)    {        // Validation omitted        UnderlyingBuilder  underlyingBuilder;    }    // ...}从而我们可以分别为不同的环境进行相应的配置。以 ConfigureService 方法为例public IWebHostBuilder ConfigureServices(ActionIServiceCollection configureServices){    UnderlyingBuilder.ConfigureServices(        (context, services)         {            if (!IsSupported(context.HostingEnvironment)) { return; }            configureServices(services);        });    return this;}按照上述方式包装 ConfigureAppConfiguration这样就可以构造以下的扩展方法public static IWebHostBuilder UseEnvironment(    this IWebHostBuilder builder,    string environmentName,     ActionIWebHostBuilder configureBuilder){    bool IsEnvironmentSupported(IHostingEnvironment h)          h.IsEnvironment(config.environmentName);    EnvironmentAwareWebHostBuilder environmentAwareBuilder         new DelegatedWebHostBuilder(builder, IsEnvironmentSupported);    config.configureBuilder(environmentAwareBuilder);    return builder;}这种方案下的 WebHostBuilder 初始化逻辑就变成了webHostBuilder    .UseEnvironment(Development, wb  {        wb            .ConfigureService((ctx, cb)  { ... })            .ConfigureLogging((lb)  { ... })            ...    })    .UseEnvironment(Production, wb  {        // configure for production    });这样我们至少就可以用若干扩展方法类将不同环境完全分开了。但是这个实现方案是有问题的UseSetting 方法。IWebHostBuilder 所公开的方法中除了 Build、ConfigureServices 和 ConfigureAppConfiguration 之外还有第四个方法UseSetting。和上述 ConfigureXxx 方法不同UseSetting 方法执行完毕之后其影响马上生效而且该方法无法根据不同的环境作出变化。即如果我们使用了webHostBuilder    .UseEnvironment(Development, wb  wb.UseSetting(Foo, Bar))    .UseEnvironment(Production, wb  wb.UseSetting(Foo, O_o));且当前环境为 Development 则 IConfiguration 实例的 Foo 对应的值为 O_o。这就会造成混淆。3.3 还是从扩展点来思考从第 2 节的论述中我们已经知道和环境相关的配置可能存在于宿主环境初始化过程中也可能存在 Startup 初始化过程中即 WebHost.Run 方法执行过程中。因此我们必须综合考虑这两个部分但是这个两个部分天生是不同的。那么强行进行统一也是不合适的。根据开闭原则我们还是应该从扩展点上来考虑。首先我们能够确定我们的 Adapter 有哪些。又有哪一些 Adapter 是和环境相关的。例如我们和环境相关的 Adapter 有 DB配置文件加载日志记录HttpClient在非 Development 环境中我们可能需要进行客户端证书验证在流水线创建过程中需要根据环境配置是否需要 HTTPS 强制跳转需要配置错误信息的详细程度等等。在梳理好这些内容后我们就能有针对性的创建方法对各个部分进行配置了我们可以使用工厂模式class WebHostConfigureFactory {    ...    public IWebHostConfigurator Create(string environmentName) {        return cachedConfigurators[environmentName];    }}而每一个 IWebHostConfigurator 中都包含了所有的环境相关配置interface IWebHostConfigurator {    void AddDatabase(IHostingEnvironment environment, IServiceCollection services);    void LoadConfiguration(IHostingEnvironment environment, IConfigurationBuilder configBuilder);    void ConfigureLogging(IHostingEnvironment environment, ILoggingBuilder loggingBuilder);    void AddHttpClient(IHostingEnvironment environment, IServiceCollection services);    void ConfigureHttpsRedirection(IHostingEnvironment environment, IConfiguration configuration, IApplicationBuilder builder);    void ConfigureErrorHandler(IHostingEnvironment environment,  IConfiguration configuration, IApplicationBuilder builder);}而这样我们为各个环境的扩展点建立了抽象从而统一配置过程static IWebHostBuilder CreateWebHostBuilder() {    return new WebHostBuilder()        .UseKestrel()        //        // Common configurations        //        .ConfigureServices((context, services)  {            IWebHostConfigurator configurator  factory.Create(context.HostingEnvironment.EnvironmentName);            configurator.AddDatabase(context.HostingEnvironment, services);            configurator.AddHttpClient(context.HostingEnvironment, services);        })        .ConfigureLogging((context, logBuilder)  {            factory                .Create(context.HostingEnvironment.EnvironmentName)                .ConfigureLogging(context.HostingEnvironment, logBuilder);        })        .UseStartupStartup();}...class Startup {    ...    public void Configure(IApplicationBuilder app) {        IWebHostConfigurator configurator  factory.Create(hostingEnvironment.EnvironmentName);        configurator.ConfigureHttpsRedirection(hostingEnvironment, configuration, app);        configurator.ConfigureErrorHandler(hostingEnvironment, configuration, app);        // Common configurations    }}4 总结请跳到文章开头 :-D参考资料R. C. Martin and R. C. Martin, Clean architecture: a craftsman’s guide to software structure and design. London, England: Prentice Hall, 2018.Unit-of-work: https://martinfowler.com/eaaCatalog/unitOfWork.htmlDependency Injection in ASP.NET Core: https://docs.microsoft.com/en-us/aspnet/core/fundamentals/dependency-injection?viewaspnetcore-2.2App startup in ASP.NET Core: https://docs.microsoft.com/en-us/aspnet/core/fundamentals/startup?viewaspnetcore-2.2Use multiple environments in ASP.NET Core: https://docs.microsoft.com/en-us/aspnet/core/fundamentals/environments?viewaspnetcore-2.2如果您觉得本文对您有帮助也欢迎分享给其他的人。我们一起进步。欢迎关注我的微信公众号
http://www.yutouwan.com/news/371742/

相关文章:

  • 去哪个网站找建筑图纸网络工程师证书报考条件
  • 男人和女人晚上做污污的视频大网站郑州男科
  • 做ae动图的网站深圳市住房和建设局门户网站
  • 农业科技公司网站案例东莞信息网
  • 光做网站推广咋样最近热搜新闻事件
  • 淘宝网站如何做虚拟网站建设配置文件无法粘贴
  • cms网站开发毕设西安大雁塔的历史简介
  • 器材管理网站开发东莞模板建网站平台
  • 网站seo优化外包黔南seo
  • 网络知识网站OA网站建设分析
  • 宁波公司招聘seo网站推广方案策划书
  • 重视网站商务通wordpress留言时间不正确
  • ps切片工具做网站新榜数据平台
  • 手机网页 模板广告优化师工资一般多少
  • 注册网站时审核是人工审核吗还是电脑审核优秀企业门户网站建设
  • 网站如何做软文推广华强北设计网站建设
  • 做一个网站的流程上海单个关键词优化
  • 广告型网站怎么做wordpress 转义
  • 手机网站开发指南做课件需要的纯音乐网站
  • 官方网站建设要点网站做收录
  • 网站关键词描述公众号注册官网
  • 传奇怎么建设自己的网站用网站模板建网站
  • 电子商务网站的建设包含哪些流程图宁波专业做网站
  • 做电商网站运营wordpress标签404
  • 网站界面用什么做的全国平面设计大赛官网
  • 网站建设与管理是学什么劳力士手表网站
  • 网站建设 客户需求专业免费建站
  • 网站建设 镇江万达WordPress文章付费系统
  • 优化网站步骤游戏科技网站
  • 建设网站话术steam交易链接在哪里看