-
Notifications
You must be signed in to change notification settings - Fork 3.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
DbContextFactory could be more tolerant of there being multiple constructors on a DbContext #24124
Comments
@lowds The |
@ajcvickers thanks for the response. I think we've just run into this situation because are migrating from using DI with DbContext, to using DbContextFactory as we bring server-side blazor into our solution. We have a stand-alone console application acting as our startup project (referencing EF design and tools packages) for creating EF migrations where rather than a web app where the DI services are configured (as our DbContext is in a .NET standard library) so the no-arg constructor was being used to support this. Our DbContext currently has two constructors:
With the two constructors everything used to work when registering a DbContext via services, but moving to DbContextFactory to support Blazor has meant that EF now expects our DbContext to have exactly one constructor. I made a small XUnit file showing this at https://gist.github.com/lowds/d029bb8eefda07d0e18a04a7f7c42daa . Currently we're working around it by registering our own CustomDbContextFactorySource in the services collection for our web app, where the custom source contains the for-loop proposed in my previous comment, though will admit this is not ideal as the IDbContextFactorySource is documented as an internal API. If when using DbContextFactory our DbContext must have exactly one constructor then long term we will look to change our migrations startup project to use one of the workarounds specific to the tooling (i.e. implement design-time factories). |
Note for triage: Related, possibly same root cause: dotnet/runtime#45119 |
Note for triage: not a duplicate of dotnet/runtime#45119. In this case, the exception is correct because both constructors are valid. However, we could in EF Core select the single parameter constructor here instead of falling back to D.I. This wouldn't fix the general case, but would make the case with these two common constructors work. |
Do you have an example how you worked around this? I'm having the same issue and I can't seem to figure this out. |
Another way to workaround it is to combine 2 similar constructors into one and allow null parameters like this:
|
When creating a DbContext we often have one constructor that accepts DbContextOptions and another no-arg constructor so the DbContext will work with the EF tooling for creating migrations. However, when using DbContextFactory having more than one constructor on the DbContext results in the factory being unable to create a new DbContext and results in an exception
This is due to the implementation of DbContextFactorySource that mandates a single public non-static constructor
efcore/src/EFCore/Internal/DbContextFactorySource.cs
Line 45 in 33570d0
Although there are work-arounds available with regards to the EF core tooling (https://docs.microsoft.com/en-gb/ef/core/cli/dbcontext-creation?tabs=dotnet-core-cli) it would be great if these were not required just because we are using DbContextFactory.
The DbContextFactorySource could be changed so the first 'if' statement is replaced with a for-each loop, iterating over each candidate constructor. The rest of the code inside the existing if statement is already checking parameter count and parameter types, so the for-each change would still allow the DbContextFactorySource to find the constructor that accepted DbContextOptions, but ignore any other constructors that may be present on the DbContext
The text was updated successfully, but these errors were encountered: