EntityFramework.Docs
EntityFramework.Docs copied to clipboard
Document materialization interceptors are singleton
MaterializationInterceptors causes More than twenty 'IServiceProvider' instances
I have an specific use case for MaterializationInterceptors
in an Net 8.0
web api.
I need to add IUserFactory
to my Workgroup
class.
here is my Workgroup
class:
public class Workgroup
{
...
public IUserFactory UserFactory { get; set; }
}
and here is my UserFactory
implementation:
public class UserFactory : IUserFactory
{
public UserFactory(Context context) { ... }
public void Create(string username, ...) { context.AddUser() // for example }
}
here is my Interceptor:
public class UserFactoryInterceptor : IMaterializationInterceptor
{
public object InitializedInstance(MaterializationInterceptionData materializationData, object instance)
{
if (instance is Workgroup entity)
{
entity.UserFactory = materializationData.Context.GetService<IUserFactory>();
}
return instance;
}
}
I have provided minimal example of this issue above that cause following exception after 20 call of an web api which make use of an instance of the Workgroup
class.
System.InvalidOperationException: An error was generated for warning 'Microsoft.EntityFrameworkCore.Infrastructure.ManyServiceProvidersCreatedWarning': More than twenty 'IServiceProvider' instances have been created for internal use by Entity Framework. This is commonly caused by injection of a new singleton service instance into every DbContext instance. For example, calling 'UseLoggerFactory' passing in a new instance each time--see https://go.microsoft.com/fwlink/?linkid=869049 for more details. This may lead to performance issues, consider reviewing calls on 'DbContextOptionsBuilder' that may require new service providers to be built. This exception can be suppressed or logged by passing event ID 'CoreEventId.ManyServiceProvidersCreatedWarning' to the 'ConfigureWarnings' method in 'DbContext.OnConfiguring' or 'AddDbContext'.
Even though I've removed Context
completely from UserFactory
class this exception is still being raised.
I think the Interceptor is registered as singleton so multiple instance of my Context
are refrenced this interceptor.
Tnx for any suggestion in advance 🌹
**UPDATE: **
Here is my Context:
public class Context : DbContext
{
public DbSet<User> Users { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
}
}
and my DI for the interceptor:
builder.Services.AddScoped<IUserFactory, UserFactory>();
builder.Services.AddDbContext<Context>(options =>
{
options.UseSqlServer(connectionString: connectionString);
options.AddInterceptors(new UserFactoryInterceptor());
});
Installed Packages
EF Core version: 8.0.4 Database provider: Microsoft.EntityFrameworkCore.SqlServer Target framework: .NET 8.0 Operating system: IDE: Visual Studio 2022 17.9.6 Microsoft.EntityFrameworkCore: Version="8.0.4" Microsoft.EntityFrameworkCore.Design: Version="8.0.4" Microsoft.EntityFrameworkCore.Relational: Version="8.0.4" Microsoft.EntityFrameworkCore.SqlServer: Version="8.0.4" Microsoft.EntityFrameworkCore.Tools: Version="8.0.4"