public IHostingEnvironment HostingEnvironment { get; } public void ConfigureServices(IServiceCollection services) { if (this.HostingEnvironment.IsDevelopment()) { services.AddScoped<IFileSystemService, LocalhostFileSystemService>(); } else { services.AddScoped<IFileSystemService, AzureFileSystemService>(); } } appsettings.json { "ApplicationMode": "Cloud" // Cloud | Localhost } public void ConfigureServices(IServiceCollection services) { var appMode = this.Configuration.GetSection("ApplicationMode").Value; if (appMode == "Localhost") { services.AddScoped<IService, LocalhostService>(); } else if (appMode == "Cloud") { services.AddScoped<IService, CloudService>(); } } public interface IService { string Name {get; set; } } public class LocalController { private readonly IService service; public LocalController(IEnumerable<IService> services) { // this.service = services.FirstOrDefault(svc => svc.Name == "local"); } } Func<IServiceProvider, TImplementation> implementationFactory IServiceProvider interface is an IoC container, which we configure in the ConfigureServices method of the Startup class. In addition, the ASP.NET Core platform also configures a number of proprietary services that will be useful to us.IHttpContextAccessor service, which provides an HttpContext object. With it, we can get comprehensive information about the current request, and based on this data, select the desired implementation: public void ConfigureServices(IServiceCollection services) { services.AddScoped<IHttpContextAccessor, HttpContextAccessor>(); services.AddScoped<LocalService>(); services.AddScoped<CloudService>(); services.AddScoped<IService>(serviceProvider => { var httpContext = serviceProvider.GetRequiredService<IHttpContextAccessor>(); return httpContext.IsLocalRequest() // IsLocalRequest() is a custom extension method, not a part of ASP.NET Core ? serviceProvider.GetService<LocalService>() : serviceProvider.GetService<CloudService>(); }); } IHttpContextAccessor implementation. In addition, we do not set the LocalService and CloudService as an implementation of the IService interface, but simply add them to the container.HttpContext , you can use the request headers, query string, form data to analyze and select the desired implementation: $.ajax({ type:"POST", beforeSend: function (request) { request.setRequestHeader("Use-local", "true"); }, url: "UseService", data: { id = 100 }, }); public void ConfigureServices(IServiceCollection services) { services.AddScoped<IHttpContextAccessor, HttpContextAccessor>(); services.AddScoped<LocalService>(); services.AddScoped<CloudService>(); services.AddScoped(serviceProvider => { var httpContext = serviceProvider.GetRequiredService<IHttpContextAccessor>().HttpContext; if (httpContext == null) { // HTTP return null; } // var queryString = httpContext.Request.Query; var requestHeaders = httpContext.Request.Headers; return requestHeaders.ContainsKey("Use-local") ? serviceProvider.GetService<LocalhostService>() as IService : serviceProvider.GetService<CloudService>() as IService; }); } IActionContextAccessor service. The choice of implementation based on the name of the action: public void ConfigureServices(IServiceCollection services) { services.AddScoped<IHttpContextAccessor, HttpContextAccessor>(); services.AddScoped<IActionContextAccessor, ActionContextAccessor>(); services.AddScoped<LocalService>(); services.AddScoped<CloudService>(); services.AddScoped<IService>(serviceProvider => { var actionName = serviceProvider.GetRequiredService<IActionContextAccessor>().ActionContext?.ActionDescriptor.Name; // , -, , , Startup if (actionName == null) return ResolveOutOfWebRequest(serviceProvider); return actionName == "UseLocalService" ? serviceProvider.GetService<LocalService>() : serviceProvider.GetService<CloudService>(); }); } Source: https://habr.com/ru/post/306996/
All Articles