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

Improve CheckContextConstructors method in EntityFrameworkServiceCollectionExtensions #33572

Closed
michaeltg17 opened this issue Apr 18, 2024 · 1 comment
Assignees
Labels
closed-no-further-action The issue is closed and no further action is planned. customer-reported

Comments

@michaeltg17
Copy link

When adding a DbContext using AddDbContext with some options, you want those options to be applied in that context. There is a checker method in the AddDbContext extension method that checks that the DbContext does not only have one parameterless constructor. However, it can have a constructor with some other arguments and still not have the DbContextOptions (or DbContextOptions) parameter. This causes the options to be ignored by the context without noticing and the expected exception is not thrown.

    private static void CheckContextConstructors<TContext>()
        where TContext : DbContext
    {
        var declaredConstructors = typeof(TContext).GetTypeInfo().DeclaredConstructors.ToList();
        if (declaredConstructors.Count == 1
            && declaredConstructors[0].GetParameters().Length == 0)
        {
            throw new ArgumentException(CoreStrings.DbContextMissingConstructor(typeof(TContext).ShortDisplayName()));
        }
    }

Exception message:

'AddDbContext' was called with configuration, but the context type '{contextType}' only declares a parameterless constructor. This means that the configuration passed to 'AddDbContext' will never be used. If configuration is passed to 'AddDbContext', then '{contextType}' should declare a constructor that accepts a DbContextOptions<{contextType}> and must pass it to the base constructor for DbContext.

Improve the CheckContextConstructors method so it really checks that the DbContext has a DbContextOptions as a parameter.

@ajcvickers
Copy link
Member

@michaeltg17 This is by-design. EF Core cannot know whether or not the parameter or parameters that are passed to the constructor will resolve a DbContextOptions or not. Just because the parameter itself is not a DbContextOptions does not mean it does not depend itself on something else with a DbContextOptions.

So the idea here is to warn for the common case where the user has forgotten, or does not know, that a constructor containing the options is needed. It is not intended to cover more advanced cases, and I don't think it is possible without knowing the D.I. system or its logic, to tell from the signature that a DbContextOptions is definitely not being injected.

@ajcvickers ajcvickers added closed-no-further-action The issue is closed and no further action is planned. and removed type-enhancement labels Apr 21, 2024
@ajcvickers ajcvickers closed this as not planned Won't fix, can't repro, duplicate, stale May 1, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
closed-no-further-action The issue is closed and no further action is planned. customer-reported
Projects
None yet
Development

No branches or pull requests

2 participants