EntityFramework.Docs icon indicating copy to clipboard operation
EntityFramework.Docs copied to clipboard

Document materialization interceptors are singleton

Open Reza-Noei opened this issue 3 months ago • 1 comments

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"

Reza-Noei avatar May 14 '24 12:05 Reza-Noei