5

I'm trying to add migration for ApiAuthorizationDbContext from another .NET Core project but cannot instantiate it from design time since I don't know how to get the 2nd parameter IOptions<OperationalStoreOptions>.

This is my DbContext constructor (which inherits my custom ApiAuthorizationDbContext that accepts TUser, TRole, TKey)

public class ApplicationDbContext : ApiAuthorizationDbContext<ApplicationUser, ApplicationRole, Guid>
{
    public ApplicationDbContext (DbContextOptions options, IOptions<OperationalStoreOptions> operationalStoreOptions)
        : base(options, operationalStoreOptions)
    {
    }

This is my DesignTimeDbContextFactory

public class DesignTimeDbContextFactory : IDesignTimeDbContextFactory<KontestDbContext>
{
    public ApplicationDbContext CreateDbContext(string[] args)
    {
        IConfiguration configuration = new ConfigurationBuilder()
            .SetBasePath(Directory.GetCurrentDirectory())
            .AddJsonFile("appsettings.json").Build();

        var builder = new DbContextOptionsBuilder<ApplicationDbContext>();
        var connectionString = configuration.GetConnectionString("DefaultConnection");
        builder.UseSqlServer(connectionString);

        return new ApplicationDbContext(builder.Options, ????); <--- how to resolve the IOptions<OperationStoreOptions> here ??
    }
}

I found an answer from this issue in GitHub but still can not figure out a way how to resolve this param.

I also tried to inject the IOptions<> to the constructor but when add-migration, it throws an exception that the parameterless constructor of DesignTimeDbContextFactory is not found

Can somebody give me a hint through this, I'm quite new to .NET Core / EF Core here and will very much appericiate if someone can help!

(I'm using .NET Core 3.0 and Entity Framework Core)

viethieule
  • 51
  • 3
  • 4

2 Answers2

10

Create OperationalStoreOptionsMigrations inheriting the IOptions and pass OperationalStoreOptionsMigrations object. See my answer.

  1. Create OperationalStoreOptionsMigrations method.

     public class OperationalStoreOptionsMigrations : 
       IOptions<OperationalStoreOptions>
     {
           public OperationalStoreOptions Value => new OperationalStoreOptions()
           {
                 DeviceFlowCodes = new TableConfiguration("DeviceCodes"),
                 EnableTokenCleanup = false,
                 PersistedGrants = new TableConfiguration("PersistedGrants"),
                 TokenCleanupBatchSize = 100,
                 TokenCleanupInterval = 3600,
           };
     }
    
  2. change DesignTimeDbContextFactory

     public class DesignTimeDbContextFactory : 
       IDesignTimeDbContextFactory<KontestDbContext>
     {
         public ApplicationDbContext CreateDbContext(string[] args)
         {
                 IConfiguration configuration = new ConfigurationBuilder()
                 .SetBasePath(Directory.GetCurrentDirectory())
                 .AddJsonFile("appsettings.json").Build();
    
                 var builder = new DbContextOptionsBuilder<ApplicationDbContext>();
                 var connectionString = 
                     configuration.GetConnectionString("DefaultConnection");
                     builder.UseSqlServer(connectionString);
    
                 return new ApplicationDbContext(builder.Options, new OperationalStoreOptionsMigrations()); 
            }
       }
    
shalitha senanayaka
  • 1,905
  • 20
  • 37
-3

Pass your IOptions<OprerationalStoreOption> as a parameter in the constructor then you can use it wherever you need to. Then register the IOptions service in theDI container. Something like this

public ApplicationDbContext CreateDbContext(string[] args, Options<OperationStoreOptions> optionsBuilder)
    {
        IConfiguration configuration = new ConfigurationBuilder()


        return new ApplicationDbContext(builder.Options, optionsBuilder);
    }


Formula12
  • 305
  • 1
  • 3
  • 14
  • 3
    I tried adding it but the CreateDbContext accepts only one argument because the class has to implement CreateDbContext in its interface IDesignTimeDbContextFactory. I also tried to inject the IOptions<> to the constructor but when add-migration, it throws an exception that the parameterless constructor of DesignTimeDbContextFactory is not found. – viethieule Nov 24 '19 at 01:57