Open efeozyer opened 1 year ago
You should generally not be doing UseApplicationServiceProvider, which mixes EF's internal services with your application's; what's you reason for doing this?
You should generally not be doing UseApplicationServiceProvider, which mixes EF's internal services with your application's; what's you reason for doing this?
I tried with/without .UseApplicationServiceProvider(), but result was same. GetService<> method behavior is strange.
Repository class shouldn't take additional dependencies, instead of that I want to use GetService method.
Thsee aren't really a reason to use UseApplicationServiceProvider; EF maintains a dependency injection (DI) service provider internally for its own purposes, as an implementation detail - you shouldn't be interfering with that unless you have a good reason to. In the same way, you should not be using DbContext.GetService()
, which is generally about getting EF's own services, and not your own.
I'm not sure exactly what you're trying to achieve, but if developing an ASP.NET application, then there's already the DI container managed by ASP.NET; that's the proper place to register your custom middleware services. Otherwise, you don't necessarily need a DI container for your service (I have no idea how it's being used); but if you do want a DI container, you have to create your own and register it there. See the documentation on dependency injection to see how to do that.
Repository class shouldn't take additional dependencies, instead of that I want to use GetService method.
Thsee aren't really a reason to use UseApplicationServiceProvider; EF maintains a dependency injection (DI) service provider internally for its own purposes, as an implementation detail - you shouldn't be interfering with that unless you have a good reason to. In the same way, you should not be using
DbContext.GetService()
, which is generally about getting EF's own services, and not your own.I'm not sure exactly what you're trying to achieve, but if developing an ASP.NET application, then there's already the DI container managed by ASP.NET; that's the proper place to register your custom middleware services. Otherwise, you don't necessarily need a DI container for your service (I have no idea how it's being used); but if you do want a DI container, you have to create your own and register it there. See the documentation on dependency injection to see how to do that.
Let's forget about what I'm trying to achieve (I can find another way or I can use IServiceProvider interface) but it's not resolves the problem. That obvious the behaviour of .GetService<> is strange.
Note for triage: Resolving multiple internal services via IEnumerable
works, but the bridge for this to the application service provider does not. Repro below.
var container = new ServiceCollection()
.AddScoped<IFoo, Foo1>()
.AddScoped<IFoo, Foo2>()
.AddDbContext<SomeDbContext>(b => b.UseSqlServer())
.BuildServiceProvider();
using (var scope = container.CreateScope())
using (var context = scope.ServiceProvider.GetService<SomeDbContext>())
{
var services = context.GetService<IEnumerable<IResettableService>>();
foreach (var service in services)
{
Console.WriteLine(service);
}
var externalServices = context.GetService<IEnumerable<IFoo>>();
foreach (var service in externalServices)
{
Console.WriteLine(service);
}
}
public class SomeDbContext : DbContext
{
public SomeDbContext(DbContextOptions<SomeDbContext> options)
: base(options)
{
}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
=> optionsBuilder
.UseSqlServer(@"Data Source=(LocalDb)\MSSQLLocalDB;Database=AllTogetherNow")
.LogTo(Console.WriteLine, LogLevel.Information)
.EnableSensitiveDataLogging();
}
public interface IFoo
{
}
public class Foo1 : IFoo
{
}
public class Foo2 : IFoo
{
}
Isn't mixing the service providers actually quite common because AddDbContext calls UseApplicationServiceProvider?
File a bug
[x] Please check that the documentation does not explain the behavior you are seeing. [x] Please search in both open and closed issues to check that your bug has not already been filed.
Description
I've developed a middleware layer for several purposes. Interestingly, while implementing and running unit tests, I discovered that the method dbContext.GetService<IEnumerable> could not resolve services. However, when I attempted to resolve a single service with the dbContext.GetService() command, the instance was successfully resolved.
InMemory and EntityFrameworkCore packages has same behavior. Inside of DbContext instance I couldn't resolve services with IEnumerable<>.
Example code
Also when I try to resolve services from application, it worked as expected.
Provider and version information
EF Core version: 7.0.10 Database provider: Microsoft.EntityFrameworkCore - 7.0.10 Namespace : Microsoft.EntityFrameworkCore.Infrastructure; Target frameworks: .NET 6.0/NET7.0 Operating system: Windows 11 Pro IDE: Microsoft Visual Studio Community 2022 (64-bit) - Current Version 17.6.1