Skip to content
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

[Nightly] Base DbContext prefers parameterless constructor when injected #4784

Closed
Grinderofl opened this issue Mar 14, 2016 · 3 comments
Closed
Labels
closed-fixed The issue has been fixed and is/will be included in the release indicated by the issue milestone. type-bug
Milestone

Comments

@Grinderofl
Copy link
Contributor

As a result of #4750

services.AddEntityFrameworkInMemoryDatabase()
                .AddDbContext<DbContext>(
                    (p, x) => x.UseInMemoryDatabase().UseInternalServiceProvider(p));

var context = provider.GetService<DbContext>(); 
// context == null 

It's only if I subclass and add a constructor that takes DbContextOptions as dependency and passes it into base that context is not null.

This is not consistent with previous alpha-beta-rc1-rc2uptolastweek behaviour, as well as Entity Framework 6's behaviour. As it's possible - using IModelCustomizer - to alter ModelBuilder from outside DbContext's OnModelBuilding method, it's used to be possible to have no application-specific DbContexts. In fact, to use Identity as anonymous, all one had to do previously is add IdentityContext! Not being able to do this violates L of SOLID.

This may potentially be relevant for DependencyInjection project.

@Grinderofl
Copy link
Contributor Author

Can be provisionally solved by doing

services.Replace(
                ServiceDescriptor.Scoped<DbContext>(provider => new DbContext(provider.GetService<DbContextOptions>())));

@Grinderofl
Copy link
Contributor Author

This is still an issue, DbContext should default to parametered constructor.

@ajcvickers
Copy link
Contributor

This was not caused by using the wrong constructor, but rather by conflicting registrations of DbContext as required by EF and the application. The internal EF registration was running first, followed by the one in AddDbContext, but since this one was using TryAdd it effectively did nothing. The reason the workaround worked is because it was forcing a new registration.

The issue would not be hit if the app service provider was not also used as EF's internal service provider, and if AddEntityFrameworkInMemoryDatabase was therefore never called by the application. This is what will be in the ASP.NET templates going forward. However, PR #4883 also fixes the issue for cases like this where the app wishes to use the same service provider for EF internal services.

Note that the built-in D.I. container will select the DbContextOptions constructor. However, it is still possible that some other D.I. container will select the parameterless constructor.

@ajcvickers ajcvickers modified the milestones: 1.0.0-rc2, 1.0.0 Mar 22, 2016
@ajcvickers ajcvickers modified the milestones: 1.0.0-rc2, 1.0.0 Oct 15, 2022
@ajcvickers ajcvickers added the closed-fixed The issue has been fixed and is/will be included in the release indicated by the issue milestone. label Oct 15, 2022
@ajcvickers ajcvickers removed their assignment Sep 1, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
closed-fixed The issue has been fixed and is/will be included in the release indicated by the issue milestone. type-bug
Projects
None yet
Development

No branches or pull requests

3 participants