.net 7 Error Sharding Example
johndcollins opened this issue · comments
Hi Jon, I'm trying to add your Sharding Example to my .net 7 Web App. I'm getting the following error: I can't seem to locate the issue.
System.AggregateException
HResult=0x80131500
Message=Some services are not able to be constructed (Error while validating the service descriptor 'ServiceType: AuthPermissions.AdminCode.ITenantChangeService Lifetime: Transient ImplementationType: MyProject.Web.Sharding.ShardingTenantChangeService': Unable to resolve service for type 'Microsoft.EntityFrameworkCore.DbContextOptions1[MyProject.Web.Sharding.ShardingSingleDbContext]' while attempting to activate 'MyProject.Web.Sharding.ShardingTenantChangeService'.) Source=Microsoft.Extensions.DependencyInjection StackTrace: at Microsoft.Extensions.DependencyInjection.ServiceProvider..ctor(ICollection
1 serviceDescriptors, ServiceProviderOptions options)
at Microsoft.Extensions.DependencyInjection.ServiceCollectionContainerBuilderExtensions.BuildServiceProvider(IServiceCollection services, ServiceProviderOptions options)
at Microsoft.Extensions.Hosting.HostApplicationBuilder.Build()
at Microsoft.AspNetCore.Builder.WebApplicationBuilder.Build()
at Program.
This exception was originally thrown at this call stack:
[External Code]
Inner Exception 1:
InvalidOperationException: Error while validating the service descriptor 'ServiceType: AuthPermissions.AdminCode.ITenantChangeService Lifetime: Transient ImplementationType: MyProject.Web.Sharding.ShardingTenantChangeService': Unable to resolve service for type 'Microsoft.EntityFrameworkCore.DbContextOptions`1[MyProject.Web.Sharding.ShardingSingleDbContext]' while attempting to activate 'MyProject.Web.Sharding.ShardingTenantChangeService'.
Inner Exception 2:
InvalidOperationException: Unable to resolve service for type 'Microsoft.EntityFrameworkCore.DbContextOptions`1[MyProject.Web.Sharding.ShardingSingleDbContext]' while attempting to activate 'MyProject.Web.Sharding.ShardingTenantChangeService'.
This is my startup code. It errors on the builder.Build() line
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
var connectionString = builder.Configuration.GetConnectionString("DefaultConnection");
builder.Services.AddDbContext(options =>
options.UseSqlServer(connectionString));
builder.Services.AddDatabaseDeveloperPageExceptionFilter();
builder.Services.AddDefaultIdentity(options =>
options.SignIn.RequireConfirmedAccount = false)
.AddEntityFrameworkStores();
builder.Services.AddControllersWithViews()
.AddRazorRuntimeCompilation();
builder.Services.RegisterAuthPermissions(options =>
{
options.TenantType = TenantTypes.SingleLevel | TenantTypes.AddSharding;
options.EncryptionKey = builder.Configuration[nameof(AuthPermissionsOptions.EncryptionKey)];
options.PathToFolderToLock = builder.Environment.WebRootPath;
options.SecondPartOfShardingFile = builder.Environment.EnvironmentName;
options.Configuration = builder.Configuration;
})
//NOTE: This uses the same database as the individual accounts DB
.UsingEfCoreSqlServer(connectionString)
.IndividualAccountsAuthentication()
.RegisterAddClaimToUser()
.RegisterAddClaimToUser()
.RegisterTenantChangeService()
.AddRolesPermissionsIfEmpty(MyProjectAppAuthSetupData.RolesDefinition)
.AddTenantsIfEmpty(MyProjectAppAuthSetupData.TenantDefinition)
.AddAuthUsersIfEmpty(MyProjectAppAuthSetupData.UsersRolesDefinition)
.RegisterFindUserInfoService()
.RegisterAuthenticationProviderReader()
.AddSuperUserToIndividualAccounts()
.SetupAspNetCoreAndDatabase(options =>
{
//Migrate individual account database
options.RegisterServiceToRunInJob<StartupServiceMigrateAnyDbContext>();
//Add demo users to the database (if no individual account exist)
options.RegisterServiceToRunInJob();
//Migrate the application part of the database
options.RegisterServiceToRunInJob<StartupServiceMigrateAnyDbContext<ShardingSingleDbContext>>();
//This seeds the invoice database (if empty)
options.RegisterServiceToRunInJob<StartupServiceSeedShardingDbContext>();
});
//This is used to set a tenant as "Down",
builder.Services.AddDistributedFileStoreCache(options =>
{
options.WhichVersion = FileStoreCacheVersions.Class;
//I override the the default first part of the FileStore cache file because there are many example apps in this repo
options.FirstPartOfCacheFileName = "MyProjectCacheFileStore";
}, builder.Environment);
//manually add services from the AuthPermissions.SupportCode project
builder.Services.AddSingleton<IGlobalChangeTimeService, GlobalChangeTimeService>(); //used for "update claims on a change" feature
builder.Services.AddSingleton<IDatabaseStateChangeEvent, TenantKeyOrShardChangeService>(); //triggers the "update claims on a change" feature
builder.Services.AddTransient<IAccessDatabaseInformation, AccessDatabaseInformation>();
builder.Services.AddTransient<ISetRemoveStatus, SetRemoveStatus>();
var app = builder.Build();
Looks like I was missing an important step in the RegisterExample6Invoices function. Maybe this should have been named differently :) Really has nothing to do with invoices.
//Register the retail database to the same database used for individual accounts and AuthP database
services.AddDbContext<ShardingSingleDbContext>(options =>
options.UseSqlServer(
configuration.GetConnectionString("DefaultConnection"), dbOptions =>
dbOptions.MigrationsHistoryTable(ShardingSingleDbContextHistoryName)));