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