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

Document materialization interceptors are singleton #4726

Open
Reza-Noei opened this issue May 14, 2024 · 1 comment
Open

Document materialization interceptors are singleton #4726

Reza-Noei opened this issue May 14, 2024 · 1 comment
Assignees
Milestone

Comments

@Reza-Noei
Copy link

Reza-Noei commented May 14, 2024

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"

@ajcvickers
Copy link
Member

@Reza-Noei Yes, this is a singleton interceptor; it generally should not hold state and the same instance should be used for all context instances. We need to document this better.

@ajcvickers ajcvickers changed the title MaterializationInterceptors causes More than twenty 'IServiceProvider' instances Document materialization interceptors are singleton May 15, 2024
@ajcvickers ajcvickers transferred this issue from dotnet/efcore May 15, 2024
@ajcvickers ajcvickers self-assigned this May 15, 2024
@ajcvickers ajcvickers added this to the Backlog milestone May 15, 2024
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