In ASP.NET Core, one of the things you can do with Microsoft\'s dependency injection framework is bind \"open generics\" (generic types unbound to a concrete type) like so:<
I also don't understand the point of your lambda expression so I'll explain to you my way of doing it.
I suppose what you wish is to reach what is explained in the article you shared
This allowed me to inspect the incoming request before supplying a dependency into the ASP.NET Core dependency injection system
My need was to inspect a custom header in the HTTP request to determine which customer is requesting my API. I could then a bit later in the pipeline decide which implementation of my IDatabaseRepository (File System or Entity Framework linked to a SQL Database) to provide for this unique request.
So I start by writing a middleware
public class ContextSettingsMiddleware
{
private readonly RequestDelegate _next;
public ContextSettingsMiddleware(RequestDelegate next, IServiceProvider serviceProvider)
{
_next = next;
}
public async Task Invoke(HttpContext context, IServiceProvider serviceProvider, IHostingEnvironment env, IContextSettings contextSettings)
{
var customerName = context.Request.Headers["customer"];
var customer = SettingsProvider.Instance.Settings.Customers.FirstOrDefault(c => c.Name == customerName);
contextSettings.SetCurrentCustomer(customer);
await _next.Invoke(context);
}
}
My SettingsProvider is just a singleton that provides me the corresponding customer object.
To let our middleware access this ContextSettings we first need to register it in ConfigureServices in Startup.cs
var contextSettings = new ContextSettings();
services.AddSingleton(contextSettings);
And in the Configure method we register our middleware
app.UseMiddleware();
Now that our customer is accessible from elsewhere let's write our Factory.
public class DatabaseRepositoryFactory
{
private IHostingEnvironment _env { get; set; }
public Func DatabaseRepository { get; private set; }
public DatabaseRepositoryFactory(IHostingEnvironment env)
{
_env = env;
DatabaseRepository = GetDatabaseRepository;
}
private IDatabaseRepository GetDatabaseRepository(IServiceProvider serviceProvider)
{
var contextSettings = serviceProvider.GetService();
var currentCustomer = contextSettings.GetCurrentCustomer();
if(SOME CHECK)
{
var currentDatabase = currentCustomer.CurrentDatabase as FileSystemDatabase;
var databaseRepository = new FileSystemDatabaseRepository(currentDatabase.Path);
return databaseRepository;
}
else
{
var currentDatabase = currentCustomer.CurrentDatabase as EntityDatabase;
var dbContext = new CustomDbContext(currentDatabase.ConnectionString, _env.EnvironmentName);
var databaseRepository = new EntityFrameworkDatabaseRepository(dbContext);
return databaseRepository;
}
}
}
In order to use serviceProvider.GetService<>() method you will need to include the following using in your CS file
using Microsoft.Extensions.DependencyInjection;
Finally we can use our Factory in ConfigureServices method
var databaseRepositoryFactory = new DatabaseRepositoryFactory(_env);
services.AddScoped(databaseRepositoryFactory.DatabaseRepository);
So every single HTTP request my DatabaseRepository will may be different depending of several parameters. I could use a file system or a SQL Database and I can get the proper database corresponding to my customer. (Yes I have multiple databases per customer, don't try to understand why)
I simplified it as possible, my code is in reality more complex but you get the idea (I hope). Now you can modify this to fit your needs.