We have an asp.net core Web API and registering our EF DB context like so
services
.AddDbContext<SiteDbContext>((serviceProvider, opt) =>
{
opt
.UseNpgsql(options.Site)
.UseInternalServiceProvider(serviceProvider)
;
})
The DB Context calls DbContextOptionsBuilder.UseLoggerFactory which fails.
Looking at this doco https://learn.microsoft.com/en-us/dotnet/api/microsoft.entityframeworkcore.dbcontextoptionsbuilder.useloggerfactory?view=efcore-5.0
It is mentioned that you can't do what I just did above and suggested to "In this case, the ILoggerFactory should be configured directly in that service provider."
My question is how is that specifically done? to configure directly in that service provider.
From the docs (emphasis mine):
Sets the IServiceProvider that the context should resolve all of its services from. EF will create and manage a service provider if none is specified.
The service provider must contain all the services required by Entity Framework (and the database being used). The Entity Framework services can be registered using an extension method on IServiceCollection. For example, the Microsoft SQL Server provider includes an AddEntityFrameworkSqlServer() method to add the required services.
You shouldn't try to replace the internal service provider with the app-level service provider unless you register every single internal service EF core needs.
If you actually need to set the logger factory, there's an easier way to configure it. Use an overload that gives you an IServiceProvider:
services.AddDbContext<AppDbContext>((provider, options) =>
{
var loggerFactory = provider.GetRequiredService<ILoggerFactory>();
options
.UseNpgsql(/* ... */)
.UseLoggerFactory(loggerFactory);
});
Related
.NET6 EFCore & Cosmos Migration issue. Need some help.
Hello folks. I am new in the world of .Net and I am facing an issue that Google has failed to help me solve. You're kind of my last regard.
So. I am trying to connect to an Azure Cosmos DB from my little HomeControlCenter Project using EFCore 6.0.3
The Error:
Unable to resolve service for type 'Microsoft.EntityFrameworkCore.Migrations.IMigrator'. This is often because no database provider has been configured for this DbContext. A provider can be configured by overriding the 'DbContext.OnConfiguring' method or by using 'AddDbContext' on the application service provider. If 'AddDbContext' is used, then also ensure that your DbContext type accepts a DbContextOptions<TContext>
object in its constructor and passes it to the base constructor for DbContext.
My Program.cs:
builder.Services.AddDbContext<ControlCenterContext>(options =>
options.UseCosmos(builder.Configuration.GetConnectionString("DefaultConnection"), "ToDoList"));
My DbContext Impl:
public class ControlCenterContext : DbContext
{
public ControlCenterContext(DbContextOptions<ControlCenterContext> options) : base(options)
{
}
}
I also tried to use an override of OnConfiguring instead of the Program.cs line.
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
=> optionsBuilder.UseCosmos(
"<AccountEndpoint>",
"<accountKey>",
databaseName: "ToDoList");
Nothing helped. When ever I run dotnet ef migrations add "initialSetup" I get the error mentioned above.
I read the error carefully and as you can see, I did apply all the necessary constructor params & other additions... I even tried to create a vanilla project and do the same all over again...
I couldn't find anything official from Microsoft, but the author of this blog states migrations using EF Core for CosmosDb are not supported: https://www.thereformedprogrammer.net/an-in-depth-study-of-cosmos-db-and-ef-core-3-0-database-provider/#1-no-migrations-can-cause-problems
This makes sense since CosmosDB is a document database, so it has no schema, it's just a bunch of JSON files. I ran into this issue when I wanted to use migrations to make seed data. The only solution I could think of was to create a separate project that uploaded the seed data with static values. But again, this was only seed data and not schema updates.
if i use default ioc in asp.net core,i can use this option :
WebHost.CreateDefaultBuilder(args)
.UseDefaultServiceProvider((context, options) => {
options.ValidateScopes = true;
})
but how to use this config in autofac? I don't see any relevant documentation on the github homepage
When ValidateScopes is set to true, the default service provider performs checks to verify that:
Scoped services aren't directly or indirectly resolved from the root service provider.
Scoped services aren't directly or indirectly injected into singletons.
ValidateScopes - as with UseDefaultServiceProvider - are both not Autofac. There is no equivalent in Autofac. There is documentation about caprice dependencies but nothing to prevent you from doing it.
I'm using Service Fabric v6.1.472. We're trying to switch to using Service Fabric Remoting (https://learn.microsoft.com/en-us/azure/service-fabric/service-fabric-reliable-services-communication-remoting), specifically to use the v2 listeners.
The problem I'm running in to is that the documentation only says how to do it using a single listener via the extension method:
protected override IEnumerable<ServiceInstanceListener> CreateServiceInstanceListeners()
{
return this.CreateServiceRemotingInstanceListeners();
}
This assumes that
The service class implements the remoting interface
There is only one remoting v2 endpoint in the host (I need multiple endpoints).
When digging into the decompiled code, it looks like this extension method uses a hard-coded endpoint name, which would make it impossible to use this for multiple remoting endpoints. Further digging revealed that many of the methods used by the extension method are marked internal.
Short of creating my own library, has anyone else found a workaround to this bit of bad design?
Edit
Microsoft updated their documentation. Under the header "Using explicit V2 classes to use the V2 stack," it is clear how to create listeners without the extension method.
I am working on Vert.x Service Discovery registering HttpEndPoints. Is there a way to specify ProxyOptions when publishing HttpEndPoint to service discovery?
Thanks,
-Rajani
You don't provide the options when creating the record but when retrieving the service reference.
ServiceReference reference = discovery.getReferenceWithConfiguration(record, new HttpClientOptions()
.setProxyOptions(proxyOptions)
.toJson());
This explained in the retrieving a service reference section of the documentation:
When retrieving a service reference you can pass a JsonObject used to
configure the service object.
The gin tutorial seems to imply that to inject remote services all you need to do is annotate with #Inject.
Do you you still need to define this in a module somewhere or is the point that you can just annotate with #Inject and it will work?
Gin has automatic support for remote services, as outlined in the tutorial you mentioned:
Every time Gin is asked to inject an asynchronous remote service, it will inject an instance retrieved through calling GWT.create on its regular remote service.
Therefore, it will 'just work'.