神刀安全网

MiddlewareBuilder For ASP.NET Core 1.0 RC2

I was reading Bill Boga’s ( @Bogaiv ) blog post "Environment name in ASP.NET Core 1.0 RC2" and noticed that the Configure method at the bottom of his post looked very iffy through no fault of his own.

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)     {         if (env.IsDevelopment())         {             // do stuff on your local machine             app.UseDeveloperExceptionPage();             app.UseBrowserLink();         }          if (env.IsStaging())         {             // do stuff on your pre-prod. machine         }          if (env.IsProduction())         {             // do stuff on your prod. machine         }          if (env.IsEnvironment("QA"))         {             // do stuff on your QA machine         }     }

If you create a new ASP.NET Core 1.0 RC2 application using Visual Studio, the Configure method looks like this.

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) {     loggerFactory.AddConsole(Configuration.GetSection("Logging"));     loggerFactory.AddDebug();      if (env.IsDevelopment())     {         app.UseDeveloperExceptionPage();         app.UseDatabaseErrorPage();         app.UseBrowserLink();     }     else     {         app.UseExceptionHandler("/Home/Error");     }      app.UseStaticFiles();      app.UseIdentity();      // Add external authentication middleware below. To configure them please see http://go.microsoft.com/fwlink/?LinkID=532715      app.UseMvc(routes =>     {         routes.MapRoute(             name: "default",             template: "{controller=Home}/{action=Index}/{id?}");     }); }

Take note of the if/else block. I wanted to see if I could write a more fluent interface that accomplishes the same thing. This is my recreation of the default Configure method.

Another Approach

new MiddlewareBuilder(app, env)     .Development((a, e) =>     {         a.UseDeveloperExceptionPage()             .UseDatabaseErrorPage()             .UseBrowserLink();     })     .When(!env.IsDevelopment(), (a, e) =>     {         a.UseExceptionHandler("/Home/Error");     })     .Always((a, e) =>     {         a.UseStaticFiles()             .UseIdentity()             .UseMvc(routes =>             {             routes.MapRoute(                 name: "default",                 template: "{controller=Home}/{action=Index}/{id?}");             });     })     .Build();

I’m not sure I like my approach over the original if/else approach so I’d like your feedback. You can find the code below if you want to try out the MiddlewareBuilder .

Some caveats to keep in mind:

  • The order of registration is determined inside the MiddlewareBuilder
  • MiddlewareBuilder only supports one action per environment
  • tested very minimally
  • registration only occurs once Build is called

The Code

public class MiddlewareBuilder {     const string AlwaysKey = "__always";     const string DevelopmentKey = "__development";     const string ProductionKey = "__production";     const string StagingKey = "__staging";      private readonly string[] allKeys = {AlwaysKey, DevelopmentKey, StagingKey, ProductionKey};      private Dictionary<string, Action<IHostingEnvironment, IApplicationBuilder>>         Environments { get; }          = new Dictionary<string, Action<IHostingEnvironment, IApplicationBuilder>>(StringComparer.CurrentCultureIgnoreCase);       private readonly IApplicationBuilder app;     private readonly IHostingEnvironment env;      public MiddlewareBuilder(IApplicationBuilder app, IHostingEnvironment env)     {         if (env == null) throw new ArgumentNullException(nameof(env));         if (app == null) throw new ArgumentNullException(nameof(app));          this.env = env;         this.app = app;     }      public MiddlewareBuilder Always(Action<IHostingEnvironment, IApplicationBuilder> setup)     {         Environments.Add(AlwaysKey, setup);         return this;     }      public MiddlewareBuilder Development(Action<IHostingEnvironment, IApplicationBuilder> setup)     {         Environments.Add(DevelopmentKey, setup);         return this;     }      public MiddlewareBuilder Production(Action<IHostingEnvironment, IApplicationBuilder> setup)     {         Environments.Add(ProductionKey, setup);         return this;     }      public MiddlewareBuilder Staging(Action<IHostingEnvironment, IApplicationBuilder> setup)     {         Environments.Add(StagingKey, setup);         return this;     }      public void Build()     {         // always         Action<IHostingEnvironment, IApplicationBuilder> always;         Environments.TryGetValue(AlwaysKey, out always);         always?.Invoke(env, app);          //development         if (env.IsDevelopment())         {             Action<IHostingEnvironment, IApplicationBuilder> development;             Environments.TryGetValue(DevelopmentKey, out development);             development?.Invoke(env, app);         }          // staging         if (env.IsStaging())         {             Action<IHostingEnvironment, IApplicationBuilder> staging;             Environments.TryGetValue(StagingKey, out staging);             staging?.Invoke(env, app);         }          // production         if (env.IsProduction())         {             Action<IHostingEnvironment, IApplicationBuilder> production;             Environments.TryGetValue(StagingKey, out production);             production?.Invoke(env, app);         }          // remaining         var remaining = Environments             .Where(x => !allKeys.Contains(x.Key, StringComparer.CurrentCultureIgnoreCase))             .Where(x => env.IsEnvironment(x.Key))             .Select(x => x.Value);          foreach (var action in remaining)         {             action(env, app);         }     } }

转载本站任何文章请注明:转载至神刀安全网,谢谢神刀安全网 » MiddlewareBuilder For ASP.NET Core 1.0 RC2

分享到:更多 ()

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址