Skip to content

Commit

Permalink
Fix NullReferenceException in background thread emitting IL in Depend…
Browse files Browse the repository at this point in the history
…encyInjection (#55340)

* Fix NullReferenceException in background thread emitting IL in DependencyInjection

When ILEmitResolverBuilder is getting created, it grabs the "Root" scope off of the ServiceProvider. However, the Root scope isn't set on ServiceProvider yet. So later when it tries to get used, it null refs. But this exception gets caught and eaten since it happens on a background thread.

The fix is to set Root before creating the ServiceProviderEngine.

* Add a debug assert that we shouldn't get exceptions from the background compilation thread
  • Loading branch information
eerhardt committed Jul 8, 2021
1 parent 7ae4d1a commit 2432926
Show file tree
Hide file tree
Showing 2 changed files with 5 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.

using System;
using System.Diagnostics;
using System.Threading;

namespace Microsoft.Extensions.DependencyInjection.ServiceLookup
Expand Down Expand Up @@ -37,6 +38,8 @@ public override Func<ServiceProviderEngineScope, object> RealizeService(ServiceC
catch (Exception ex)
{
DependencyInjectionEventSource.Log.ServiceRealizationFailed(ex);
Debug.Fail($"We should never get exceptions from the background compilation.{Environment.NewLine}{ex}");
}
},
null);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,12 @@ public sealed class ServiceProvider : IServiceProvider, IDisposable, IAsyncDispo

internal ServiceProvider(IEnumerable<ServiceDescriptor> serviceDescriptors, ServiceProviderOptions options)
{
// note that Root needs to be set before calling GetEngine(), because the engine may need to access Root
Root = new ServiceProviderEngineScope(this, isRootScope: true);
_engine = GetEngine();
_createServiceAccessor = CreateServiceAccessor;
_realizedServices = new ConcurrentDictionary<Type, Func<ServiceProviderEngineScope, object>>();

Root = new ServiceProviderEngineScope(this, isRootScope: true);
CallSiteFactory = new CallSiteFactory(serviceDescriptors);
// The list of built in services that aren't part of the list of service descriptors
// keep this in sync with CallSiteFactory.IsService
Expand Down

0 comments on commit 2432926

Please sign in to comment.