Skip to content

Commit

Permalink
Use different internal service provider when EnableNullChecks is chan…
Browse files Browse the repository at this point in the history
…ged (#29057)
  • Loading branch information
ajcvickers authored Sep 12, 2022
1 parent 307b818 commit fbc10ec
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,11 @@ public override string LogFragment

builder.Append("StoreName=").Append(Extension._storeName).Append(' ');

if (!Extension._nullabilityCheckEnabled)
{
builder.Append("NullabilityChecksEnabled ");
}

_logFragment = builder.ToString();
}

Expand All @@ -183,14 +188,24 @@ public override string LogFragment
}

public override int GetServiceProviderHashCode()
=> Extension._databaseRoot?.GetHashCode() ?? 0;
{
var hashCode = new HashCode();
hashCode.Add(Extension._databaseRoot);
hashCode.Add(Extension._nullabilityCheckEnabled);
return hashCode.ToHashCode();
}

public override bool ShouldUseSameServiceProvider(DbContextOptionsExtensionInfo other)
=> other is ExtensionInfo otherInfo
&& Extension._databaseRoot == otherInfo.Extension._databaseRoot;
&& Extension._databaseRoot == otherInfo.Extension._databaseRoot
&& Extension._nullabilityCheckEnabled == otherInfo.Extension._nullabilityCheckEnabled;

public override void PopulateDebugInfo(IDictionary<string, string> debugInfo)
=> debugInfo["InMemoryDatabase:DatabaseRoot"]
{
debugInfo["InMemoryDatabase:DatabaseRoot"]
= (Extension._databaseRoot?.GetHashCode() ?? 0).ToString(CultureInfo.InvariantCulture);
debugInfo["InMemoryDatabase:NullabilityChecksEnabled"]
= (!Extension._nullabilityCheckEnabled).GetHashCode().ToString(CultureInfo.InvariantCulture);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,15 @@ public virtual void Validate(IDbContextOptions options)
nameof(InMemoryDbContextOptionsExtensions.UseInMemoryDatabase),
nameof(DbContextOptionsBuilder.UseInternalServiceProvider)));
}

if (inMemoryOptions != null
&& IsNullabilityCheckEnabled != inMemoryOptions.IsNullabilityCheckEnabled)
{
throw new InvalidOperationException(
CoreStrings.SingletonOptionChanged(
nameof(InMemoryDbContextOptionsBuilder.EnableNullChecks),
nameof(DbContextOptionsBuilder.UseInternalServiceProvider)));
}
}

/// <summary>
Expand Down
61 changes: 61 additions & 0 deletions test/EFCore.InMemory.FunctionalTests/GlobalDatabaseTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,29 @@ public void Global_store_can_be_used_when_AddDbContext_force_different_internal_
}
}

[ConditionalFact]
public void EnableNullChecks_forces_different_internal_service_provider()
{
using var context1 = new ChangeNullabilityChecksContext(enableNullChecks: true);
using var context2 = new ChangeNullabilityChecksContext(enableNullChecks: false);
Assert.NotSame(((IInfrastructure<IServiceProvider>)context1).Instance, ((IInfrastructure<IServiceProvider>)context2).Instance);
}

private class ChangeNullabilityChecksContext : DbContext
{
private readonly bool _enableNullChecks;

public ChangeNullabilityChecksContext(bool enableNullChecks)
{
_enableNullChecks = enableNullChecks;
}

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
=> optionsBuilder
.UseInMemoryDatabase(nameof(ChangeNullabilityChecksCacheContext),
b => b.EnableNullChecks(_enableNullChecks));
}

[ConditionalFact]
public void Throws_changing_global_store_in_OnConfiguring_when_UseInternalServiceProvider()
{
Expand Down Expand Up @@ -181,6 +204,44 @@ protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
.UseInMemoryDatabase(nameof(ChangeSdlCacheContext), _on ? _databaseRoot : null);
}

[ConditionalFact]
public void Throws_changing_nullability_checks_in_OnConfiguring_when_UseInternalServiceProvider()
{
using (var context = new ChangeNullabilityChecksCacheContext(false))
{
Assert.NotNull(context.Model);
}

using (var context = new ChangeNullabilityChecksCacheContext(true))
{
Assert.Equal(
CoreStrings.SingletonOptionChanged(
nameof(InMemoryDbContextOptionsBuilder.EnableNullChecks),
nameof(DbContextOptionsBuilder.UseInternalServiceProvider)),
Assert.Throws<InvalidOperationException>(() => context.Model).Message);
}
}

private class ChangeNullabilityChecksCacheContext : DbContext
{
private static readonly IServiceProvider _serviceProvider
= new ServiceCollection()
.AddEntityFrameworkInMemoryDatabase()
.BuildServiceProvider(validateScopes: true);

private readonly bool _on;

public ChangeNullabilityChecksCacheContext(bool on)
{
_on = on;
}

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
=> optionsBuilder
.UseInternalServiceProvider(_serviceProvider)
.UseInMemoryDatabase(nameof(ChangeSdlCacheContext), b => b.EnableNullChecks(_on));
}

private class BooFooContext : DbContext
{
public BooFooContext(DbContextOptions options)
Expand Down

0 comments on commit fbc10ec

Please sign in to comment.