vendredi 1 mai 2020

How to invoke generic method with Action

I want this code to be called generic.

services.AddDbContext<ProductsDbContext>(options =>
{
    options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"),
        sqlServerOptions =>
        {
            sqlServerOptions.MigrationsAssembly("Modules.Products");
        });
});

It's from entityframeworkcore. See the documentation here.

I created a class for getting the builder:

public static class DbContextExtensions
{
    public static Action<DbContextOptionsBuilder> GetDbContextOptionsBuilder(string connectionString, AssemblyName moduleName)
    {
        return options =>
        {
            options.UseSqlServer(connectionString,
                sqlServerOptions =>
                {
                    sqlServerOptions.MigrationsAssembly(moduleName.Name);
                });
        };
    }
}

And I created the following for invoke the method:

var moduleAssembly = Assembly.GetAssembly(manifest);
var moduleName = moduleAssembly.GetName();

// Get dbcontext like ProductsDbContext
var dbContext = moduleAssembly.GetTypes().Where(p => typeof(DbContext).IsAssignableFrom(p)).First();

// Get the correct extensionmethod with Action<DbContextOptionsBuilder>
MethodInfo addDbContextMethod = typeof(EntityFrameworkServiceCollectionExtensions)
    .GetMethod(nameof(EntityFrameworkServiceCollectionExtensions.AddDbContext),
        1,
        new Type[] { typeof(ServiceCollection), typeof(Action<DbContextOptionsBuilder>), typeof(ServiceLifetime), typeof(ServiceLifetime) });
MethodInfo generic = addDbContextMethod.MakeGenericMethod(dbContext);


// But how to pass the Action<DbContextOptionsBuilder> method?
// I tried the following but i'm lost...
var delegateType = typeof(Action<>).MakeGenericType(typeof(DbContextOptionsBuilder));
var methodInfo = typeof(DbContextExtensions).GetMethod(nameof(DbContextExtensions.GetDbContextOptionsBuilder));
var del = Delegate.CreateDelegate(delegateType, null, methodInfo);

// invoke subscribe method
generic.Invoke(services, new[] { del });

Any ideas? Thanks





Aucun commentaire:

Enregistrer un commentaire