我有一个分层的Web应用程序,其中“基础结构”项目仅包含“身份”,而“持久性”包含所有其他实体。对于持久性,我设法生成了迁移,但是对于基础结构却无法。两者的区别在于持久性继承了DbContext和Infrastrutcure ApiauthorizationDbContext
代码如下:
public class ApplicationDbContext : ApiauthorizationDbContext<ApplicationUser>
{
public ApplicationDbContext(
DbContextOptions<ApplicationDbContext> options,IOptions<OperationalStoreOptions> operationalStoreOptions) : base(options,operationalStoreOptions)
{
}
} public class IMSDbContext : DbContext,IIMSDbContext
{
private readonly ICurrentUserService _currentUserService;
private readonly IDateTime _dateTime;
public IMSDbContext(DbContextOptions<IMSDbContext> options) : base(options)
{
}
public IMSDbContext(DbContextOptions<IMSDbContext> options,ICurrentUserService currentUserService,IDateTime dateTime) : base(options)
{
_currentUserService = currentUserService;
_dateTime = dateTime;
}
public DbSet<ItemType> ItemTypes { get; set; }
public DbSet<Item> Items { get; set; }
public DbSet<Employee> Employees { get; set; }
public DbSet<ItemDetail> ItemDetails { get; set; }
public DbSet<Location> Locations { get; set; }
public DbSet<ItemImage> ItemImages { get; set; }
public override Task<int> SaveChangesAsync(CancellationToken cancellationToken = new CancellationToken())
{
foreach (var entry in ChangeTracker.Entries<AuditableEntity>())
{
switch (entry.State)
{
case EntityState.Added:
entry.Entity.CreatedBy = _currentUserService.UserId;
entry.Entity.Created = _dateTime.Now;
break;
case EntityState.Modified:
entry.Entity.ModifiedBy = _currentUserService.UserId;
entry.Entity.Modified = _dateTime.Now;
break;
}
}
return base.SaveChangesAsync(cancellationToken);
}
protected override void OnmodelCreating(ModelBuilder modelBuilder)
{
modelBuilder.ApplyConfigurationsFromAssembly(typeof(IMSDbContext).Assembly);
}
}
当我从安装了EFCore.Design的Persistence项目中运行add-migration Identity -p Infrastructure -c ApplicationDbContext时 得到下一个错误:
无法创建类型为“ ApplicationDbContext”的对象。为了 设计时支持的不同模式,请参阅 https://go.microsoft.com/fwlink/?linkid=851728
这里是基础架构的DI:
public static class DependencyInjection
{
public static IServiceCollection AddInfrastructure(this IServiceCollection services,IConfiguration configuration,IWebHostEnvironment environment)
{
services.AddScoped<IUserManager,UserManagerService>();
services.AddTransient<INotificationService,NotificationService>();
services.AddTransient<IDateTime,MachineDateTime>();
services.AddDbContext<ApplicationDbContext>(
options => options.UseSqlServer(configuration.getconnectionString("IMSDatabase")));
services.AddDefaultIdentity<ApplicationUser>()
.AddEntityFrameworkStores<ApplicationDbContext>();
services.AddIdentityServer()
.AddApiauthorization<ApplicationUser,ApplicationDbContext>();
services.AddAuthentication()
.AddIdentityServerJwt();
return services;
}
}
这是WebAPI项目的启动。
public class Startup
{
private IServiceCollection _services;
public Startup(IConfiguration configuration,IWebHostEnvironment environment)
{
Configuration = configuration;
Environment = environment;
}
public IConfiguration Configuration { get; }
public IWebHostEnvironment Environment { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddInfrastructure(Configuration,Environment);
services.AddPersistence(Configuration);
services.AddApplication();
services.AddControllers();
_services = services;
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app,IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthentication();
app.UseIdentityServer();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
private void RegisteredServicesPage(IApplicationBuilder app)
{
app.Map("/services",builder => builder.Run(async context =>
{
var sb = new StringBuilder();
sb.Append("<h1>Registered Services</h1>");
sb.Append("<table><thead>");
sb.Append("<tr><th>Type</th><th>Lifetime</th><th>Instance</th></tr>");
sb.Append("</thead><tbody>");
foreach (var svc in _services)
{
sb.Append("<tr>");
sb.Append($"<td>{svc.ServiceType.FullName}</td>");
sb.Append($"<td>{svc.Lifetime}</td>");
sb.Append($"<td>{svc.ImplementationType?.FullName}</td>");
sb.Append("</tr>");
}
sb.Append("</tbody></table>");
await context.Response.WriteAsync(sb.ToString());
}));
}
}
有人可以帮助我了解我做错了什么吗? 亲切的问候, 丹尼尔(Danijel)
更新 当运行pmc命令时:
add-migration Identity -c ApplicationDbContext -p Infrastructure -s Persistence -v
Using project 'src\Infrastructure'.
Using startup project 'src\Persistence'.
Build started...
Build succeeded.
C:\Program Files\dotnet\dotnet.exe exec --depsfile C:\Users\BoksanD\source\repos\IMS\Persistence\bin\Debug\netcoreapp3.0\IMS.Persistence.deps.json --additionalprobingpath C:\Users\BoksanD\.nuget\packages --additionalprobingpath C:\microsoft\Xamarin\NuGet --additionalprobingpath "C:\Program Files\dotnet\sdk\NuGetFallbackFolder" --runtimeconfig C:\Users\BoksanD\source\repos\IMS\Persistence\bin\Debug\netcoreapp3.0\IMS.Persistence.runtimeconfig.json C:\Users\BoksanD\.nuget\packages\microsoft.entityframeworkcore.tools\3.0.0\tools\netcoreapp2.0\any\ef.dll migrations add Identity --json --context ApplicationDbContext --verbose --no-color --prefix-output --assembly C:\Users\BoksanD\source\repos\IMS\Persistence\bin\Debug\netcoreapp3.0\IMS.Infrastructure.dll --startup-assembly C:\Users\BoksanD\source\repos\IMS\Persistence\bin\Debug\netcoreapp3.0\IMS.Persistence.dll --project-dir C:\Users\BoksanD\source\repos\IMS\Infrastructure\ --language C# --working-dir C:\Users\BoksanD\source\repos\IMS --root-namespace IMS.Infrastructure
Using assembly 'IMS.Infrastructure'.
Using startup assembly 'IMS.Persistence'.
Using application base 'C:\Users\BoksanD\source\repos\IMS\Persistence\bin\Debug\netcoreapp3.0'.
Using working directory 'C:\Users\BoksanD\source\repos\IMS\Persistence'.
Using root namespace 'IMS.Infrastructure'.
Using project directory 'C:\Users\BoksanD\source\repos\IMS\Infrastructure\'.
Finding DbContext classes...
Finding IDesignTimeDbContextFactory implementations...
Found IDesignTimeDbContextFactory implementation 'IMSDbContextFactory'.
Found DbContext 'IMSDbContext'.
Finding application service provider...
Finding microsoft.Extensions.Hosting service provider...
No static method 'CreateHostBuilder(string[])' was found on class 'Program'.
No application service provider was found.
Finding DbContext classes in the project...
Found DbContext 'ApplicationDbContext'.
microsoft.EntityFrameworkCore.Design.OperationException: Unable to create an object of type 'ApplicationDbContext'. For the different patterns supported at design time,see https://go.microsoft.com/fwlink/?linkid=851728
---> System.MissingMethodException: No parameterless constructor defined for type 'IMS.Infrastructure.Identity.ApplicationDbContext'.
at System.RuntimeType.CreateInstanceDefaultCtorSlow(Boolean publicOnly,Boolean wrapExceptions,Boolean fillCache)
at System.RuntimeType.CreateInstanceDefaultCtor(Boolean publicOnly,Boolean skipCheckThis,Boolean fillCache,Boolean wrapExceptions)
at System.activator.CreateInstance(Type type,Boolean nonPublic,Boolean wrapExceptions)
at System.activator.CreateInstance(Type type)
at microsoft.EntityFrameworkCore.Design.Internal.DbContextOperations.<>c__DisplayClass13_3.<FindContextTypes>b__13()
--- End of inner exception stack trace ---
at microsoft.EntityFrameworkCore.Design.Internal.DbContextOperations.<>c__DisplayClass13_3.<FindContextTypes>b__13()
at microsoft.EntityFrameworkCore.Design.Internal.DbContextOperations.CreateContext(Func`1 factory)
at microsoft.EntityFrameworkCore.Design.Internal.DbContextOperations.CreateContext(String contextType)
at microsoft.EntityFrameworkCore.Design.Internal.MigrationsOperations.AddMigration(String name,String outputDir,String contextType)
at microsoft.EntityFrameworkCore.Design.OperationExecutor.AddMigrationImpl(String name,String contextType)
at microsoft.EntityFrameworkCore.Design.OperationExecutor.AddMigration.<>c__DisplayClass0_0.<.ctor>b__0()
at microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.<>c__DisplayClass3_0`1.<Execute>b__0()
at microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.Execute(action action)
Unable to create an object of type 'ApplicationDbContext'. For the different patterns supported at design time,see https://go.microsoft.com/fwlink/?linkid=851728
这是Program.cs
namespace IMS.WebAPI
{
public class Program
{
public static void Main(string[] args)
{
var host = CreateHostBuilder(args).Build();
using (var scope = host.Services.CreateScope())
{
var services = scope.ServiceProvider;
try
{
var northwindContext = services.GetRequiredService<IMSDbContext>();
northwindContext.Database.Migrate();
var identityContext = services.GetRequiredService<ApplicationDbContext>();
identityContext.Database.Migrate();
}
catch (Exception ex)
{
var logger = scope.ServiceProvider.GetRequiredService<ILogger<Program>>();
logger.LogError(ex,"An error occurred while migrating or initializing the database.");
}
}
host.Run();
}
public static IWebHostBuilder CreateHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.ConfigureAppConfiguration((hostingContext,config) =>
{
var env = hostingContext.HostingEnvironment;
config.AddJsonFile("appsettings.json",optional: true,reloadOnChange: true)
.AddJsonFile($"appsettings.{env.EnvironmentName}.json",reloadOnChange: true);
if (env.IsDevelopment())
{
var appAssembly = Assembly.Load(new AssemblyName(env.ApplicationName));
if (appAssembly != null)
{
config.AddUserSecrets(appAssembly,optional: true);
}
}
config.AddEnvironmentVariables();
if (args != null)
{
config.AddCommandLine(args);
}
})
.ConfigureLogging((hostingContext,logging) =>
{
logging.AddConfiguration(hostingContext.Configuration.GetSection("Logging"));
logging.AddConsole();
logging.AddDebug();
})
.UseStartup<Startup>();
}
}