Reputation: 509
I try to separate EF Core migrations into a separate class library. I have an API project which references the class library with migrations.
I added
to both projects.
In the migrations class library, I have an extension method where I register DbContext
into services:
public static IServiceCollection AddTMS(this IServiceCollection services, IConfiguration configuration)
{
var tmsConfiguration = configuration.GetSection("TMS");
services.AddDbContext<TMSDbContext>(opt =>
{
opt.UseSqlServer(tmsConfiguration.GetSection("ConnectionString").Value, sqlOpt =>
{
sqlOpt.MigrationsHistoryTable("_TMSMigrationsHistory");
sqlOpt.MigrationsAssembly(typeof(TMSDbContext).AssemblyQualifiedName);
});
});
return services;
}
This extension method is then called in Startup.ConfigureServices
method. When I try to add initial migration into class library project via
dotnet ef migrations add InitialMigration --project .\TMS.csproj --startup-project ..\API\API.csproj --output-dir ./Database/Migrations --context TMSDbContext --verbose
then creating migration fails with this error:
Using application service provider from Microsoft.Extensions.Hosting.
Found DbContext 'TMSDbContext'.
Finding DbContext classes in the project...
Found DbContext 'BOSDbContext'.
Found DbContext 'BOSCommonDbContext'.
Using context 'TMSDbContext'.
Finding design-time services for provider 'Microsoft.EntityFrameworkCore.SqlServer'...
Using design-time services from provider 'Microsoft.EntityFrameworkCore.SqlServer'.
Finding design-time services referenced by assembly 'API'...
Finding design-time services referenced by assembly 'TMS'...
No referenced design-time services were found.
Finding IDesignTimeServices implementations in assembly 'API'...
No design-time services were found.System.IO.FileLoadException: The given assembly name or codebase was invalid.
I know that if I implement IDesignTimeDbContextFactory<T>
to create DbContext
then it will work, but can it work without implementing this stupid interface?
Upvotes: 1
Views: 390
Reputation: 509
By the time I have found the solution. The right implmentation for AddTMS method looks like this:
public static IServiceCollection AddTMS(this IServiceCollection services, IConfiguration configuration)
{
var tmsConfiguration = configuration.GetSection("TMS");
services.AddDbContext<TMSDbContext>(opt =>
{
opt.UseSqlServer(tmsConfiguration.GetSection("ConnectionString").Value, sqlOpt =>
{
sqlOpt.MigrationsHistoryTable("_TMSMigrationsHistory");
sqlOpt.MigrationsAssembly(typeof(TMSDbContext).Assembly.FullName);
});
});
return services;
}
See the difference in
sqlOpt.MigrationsAssembly(typeof(TMSDbContext).AssemblyQualifiedName);
vs.
sqlOpt.MigrationsAssembly(typeof(TMSDbContext).Assembly.FullName);
Upvotes: 1