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

Help in getting a custom IServiceProvider working with the NodaTime NuGet package. #27566

Closed
StevenRasmussen opened this issue Mar 4, 2022 · 4 comments

Comments

@StevenRasmussen
Copy link

Preface: I am the author of the EF Core NodaTime NuGet package whose project is located here: EFCore.SqlServer.NodaTime.

I originally had an issue which I ran into when upgrading my project to support .Net 6 (see here). Through some assistance I was able to get it working, which it does as long as you use the default IServiceProvider.

A user is running into an issue when registering a custom IServiceProvider (ticket here). I have been able to reproduce the issue and have created a new branch and added a unit test to help with debugging the issue.

The exception that is thrown is:

Message: 
    System.ArgumentNullException : Value cannot be null. (Parameter 'provider')

  Stack Trace: 
    ServiceProviderServiceExtensions.GetRequiredService[T](IServiceProvider provider)
    DbContextServices.CreateModel(Boolean designTime)
    DbContextServices.get_Model()
    <>c.<TryAddCoreServices>b__8_4(IServiceProvider p)
    CallSiteRuntimeResolver.VisitFactory(FactoryCallSite factoryCallSite, RuntimeResolverContext context)
    CallSiteVisitor`2.VisitCallSiteMain(ServiceCallSite callSite, TArgument argument)
    CallSiteRuntimeResolver.VisitCache(ServiceCallSite callSite, RuntimeResolverContext context, ServiceProviderEngineScope serviceProviderEngine, RuntimeResolverLock lockType)
    CallSiteRuntimeResolver.VisitScopeCache(ServiceCallSite callSite, RuntimeResolverContext context)
    CallSiteVisitor`2.VisitCallSite(ServiceCallSite callSite, TArgument argument)
    CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite constructorCallSite, RuntimeResolverContext context)
    CallSiteVisitor`2.VisitCallSiteMain(ServiceCallSite callSite, TArgument argument)
    CallSiteRuntimeResolver.VisitCache(ServiceCallSite callSite, RuntimeResolverContext context, ServiceProviderEngineScope serviceProviderEngine, RuntimeResolverLock lockType)
    CallSiteRuntimeResolver.VisitScopeCache(ServiceCallSite callSite, RuntimeResolverContext context)
    CallSiteVisitor`2.VisitCallSite(ServiceCallSite callSite, TArgument argument)
    CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite constructorCallSite, RuntimeResolverContext context)
    CallSiteVisitor`2.VisitCallSiteMain(ServiceCallSite callSite, TArgument argument)
    CallSiteRuntimeResolver.VisitCache(ServiceCallSite callSite, RuntimeResolverContext context, ServiceProviderEngineScope serviceProviderEngine, RuntimeResolverLock lockType)
    CallSiteRuntimeResolver.VisitScopeCache(ServiceCallSite callSite, RuntimeResolverContext context)
    CallSiteVisitor`2.VisitCallSite(ServiceCallSite callSite, TArgument argument)
    CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite constructorCallSite, RuntimeResolverContext context)
    CallSiteVisitor`2.VisitCallSiteMain(ServiceCallSite callSite, TArgument argument)
    CallSiteRuntimeResolver.VisitCache(ServiceCallSite callSite, RuntimeResolverContext context, ServiceProviderEngineScope serviceProviderEngine, RuntimeResolverLock lockType)
    CallSiteRuntimeResolver.VisitScopeCache(ServiceCallSite callSite, RuntimeResolverContext context)
    CallSiteVisitor`2.VisitCallSite(ServiceCallSite callSite, TArgument argument)
    CallSiteRuntimeResolver.VisitIEnumerable(IEnumerableCallSite enumerableCallSite, RuntimeResolverContext context)
    CallSiteVisitor`2.VisitCallSiteMain(ServiceCallSite callSite, TArgument argument)
    CallSiteRuntimeResolver.VisitCache(ServiceCallSite callSite, RuntimeResolverContext context, ServiceProviderEngineScope serviceProviderEngine, RuntimeResolverLock lockType)
    CallSiteRuntimeResolver.VisitScopeCache(ServiceCallSite callSite, RuntimeResolverContext context)
    CallSiteVisitor`2.VisitCallSite(ServiceCallSite callSite, TArgument argument)
    CallSiteRuntimeResolver.Resolve(ServiceCallSite callSite, ServiceProviderEngineScope scope)
    <>c__DisplayClass2_0.<RealizeService>b__0(ServiceProviderEngineScope scope)
    ServiceProvider.GetService(Type serviceType, ServiceProviderEngineScope serviceProviderEngineScope)
    ServiceProviderEngineScope.GetService(Type serviceType)
    ServiceProviderServiceExtensions.GetService[T](IServiceProvider provider)
    NodaTimeOptionsExtension.Validate(IDbContextOptions options) line 34
    ServiceProviderCache.ValidateOptions(IDbContextOptions options)
    ServiceProviderCache.GetOrAdd(IDbContextOptions options, Boolean providerRequired)
    DbContext.ctor(DbContextOptions options)
    RacingContext.ctor(DbContextOptions options) line 15
    ServiceCollectionTest.CustomServiceCollection_ShouldNotThrowError() line 25

Similar to my original ticket above, I'm not sure if there is a bug in EFCore or if there is something wrong with how the services are being registered here

If I comment out the registration of any of the IMethodCallTranslatorPlugin (lines 15-20) then the exception does not occur.

I apologize for reaching out here for support on this as I know your time is valuable but I'm at a loss on this one. I've tried debugging with the source symbols downloaded and navigating through the EF code but without any luck as it's a little over my head how the internal registration works. I appreciate any assistance with this.

@ajcvickers
Copy link
Contributor

@StevenRasmussen Looks like the issue discussed in #27276.

Breaking change docs for this are here: https://docs.microsoft.com/en-us/ef/core/what-is-new/ef-core-6.0/breaking-changes#query-services

Let us know if this doesn't help. Appreciate your work on the Noda time plugin. 👏 👏 👏

@StevenRasmussen
Copy link
Author

Thanks for the quick response! Unfortunately, it doesn't help :( The documentation suggests using TryAdd, which is what I had to change it to in order to get it to work with .Net 6. Unfortunately, the error still throws when using a custom IServiceProvider and calling UseInternalServiceProvider. I also tried the suggestion of using AddScoped to register the services, also to no avail.

@ajcvickers
Copy link
Contributor

@StevenRasmussen Tracked down the issue and sent a PR to fix: StevenRasmussen/EFCore.SqlServer.NodaTime#28

@StevenRasmussen
Copy link
Author

Thanks!

@ajcvickers ajcvickers reopened this Oct 16, 2022
@ajcvickers ajcvickers closed this as not planned Won't fix, can't repro, duplicate, stale Oct 16, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants