-
Notifications
You must be signed in to change notification settings - Fork 3.2k
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
DbContextFactory: Multiple constructors accepting all given argument types have been found in type #25273
Comments
Have you tried moving the parameterless constructor down (or removing it) ? |
I just tried this and it unfortunately made no difference. I did forget to mention that the DbContext works perfectly without using the DbContextFactory. The DbContext is also hosted in an external project (because it is used by multiple projects, also non Blazor projects). |
@Schoof-T This is an error from dependency injection, which does not support multiple matching constructors. However, if I understand correctly, you don't get this error when using AddDbContext, which seems strange, since that will also resolve the context from D.I. Can you confirm that using AddDbContext works while AddDbContextFactory does not work with the same DbContext type? |
@ajcvickers Can confirm I do not have this issue with AddDbContext. But I also do not have multiple matching constructors, I think? So this works //Startup.cs
services.AddDbContext<ExampleDbContext>(options => options.UseOracle(configuration["ConnectionStrings:ExampleConnection"]));
//TestClass.cs
private ExampleDbContext _context;
public CertificatesTests(ExampleDbContext context)
{
_context = context;
}
[Fact]
public void Certificate_GetCertificatesFromView()
{
try
{
var result = _context.Certificates.ToList();
}
catch (Exception e)
{
throw new XunitException($"Failed to perform a DB get for entity {nameof(Certificate)} because of exception {e.InnerException?.Message ?? e.Message}.");
}
} This does not work: //Startup.cs
services.AddDbContextFactory<ExampleDbContext>(options => options.UseOracle(configuration["ConnectionStrings:ExampleConnection"]));
//TestClass.cs
private IDbContextFactory<ExampleDbContext> _dbFactory;
public CertificatesTests(IDbContextFactory<ExampleDbContext> dbFactory)
{
_dbFactory = dbFactory;
}
[Fact]
public void Certificate_GetCertificatesFromView()
{
try
{
var _context = _dbFactory.CreateDbContext();
var result = _context.Certificates.ToList();
}
catch (Exception e)
{
throw new XunitException($"Failed to perform a DB get for entity {nameof(Certificate)} because of exception {e.InnerException?.Message ?? e.Message}.");
}
}
} |
@Schoof-T This looks related to dotnet/runtime#46132. You can tell D.I. which constructor to use using an attribute: [ActivatorUtilitiesConstructor]
public ExampleDbContext(DbContextOptions<ExampleDbContext> options, IHttpContextAccessor httpContextAccessor) :
base(options)
{
_httpContextAccessor = httpContextAccessor;
} |
@davidfowl Is this going to be fixed, or is it a limitation of ActivatorUtilities? Stand-alone repo: public class ExampleDbContext : DbContext
{
private readonly IHttpContextAccessor _httpContextAccessor;
public ExampleDbContext()
{
}
public ExampleDbContext(IHttpContextAccessor httpContextAccessor)
{
_httpContextAccessor = httpContextAccessor;
}
public ExampleDbContext(DbContextOptions<ExampleDbContext> options, IHttpContextAccessor httpContextAccessor) :
base(options)
{
_httpContextAccessor = httpContextAccessor;
}
public ExampleDbContext(DbContextOptions<ExampleDbContext> options) : base(options)
{
}
}
public class FakeHttpContextAccessor : IHttpContextAccessor
{
public HttpContext HttpContext { get; set; }
}
public class Program
{
public static void Main()
{
WithoutFactory();
WithFactory();
}
private static void WithoutFactory()
{
var serviceProvider = new ServiceCollection()
.AddScoped<IHttpContextAccessor, FakeHttpContextAccessor>()
.AddDbContext<ExampleDbContext>(options => options.UseSqlite("Data Source=test.db"))
.BuildServiceProvider();
using (var scope = serviceProvider.CreateScope())
{
var context = scope.ServiceProvider.GetService<ExampleDbContext>();
Console.WriteLine(context.GetType());
}
}
private static void WithFactory()
{
var serviceProvider = new ServiceCollection()
.AddScoped<IHttpContextAccessor, FakeHttpContextAccessor>()
.AddDbContextFactory<ExampleDbContext>(options => options.UseSqlite("Data Source=test.db"))
.BuildServiceProvider();
using (var scope = serviceProvider.CreateScope())
{
var factory = scope.ServiceProvider.GetService<IDbContextFactory<ExampleDbContext>>();
Console.WriteLine(factory.GetType());
Console.WriteLine(factory.CreateDbContext().GetType());
}
}
} |
Fixed in .NET 6? No, it's been punted to 7 at the moment |
@davidfowl 7 is fine. Thanks! |
Hi, sorry for the late reply (I was on vacation) and thanks for the help! Although I think I'm missing something here. Doesn't the attribute make the DI always try to find the classes of your chosen constructor? |
A quick workaroud I use currently: CoreContext.cs has multiple constructors (generated by scaffolding with EF tools)
CoreContextActivator.cs additional context file, created manually
The trick is, to utilize the partial class and add another constructor with the ActivatorUtillitiesConstructor attribute. |
Does this make it work, but now my I've tried it like this as well, but no luck.
|
Ask a question
While implementing the DbContextFactory in our Blazor Server application (per described in https://docs.microsoft.com/en-us/aspnet/core/blazor/blazor-server-ef-core?view=aspnetcore-5.0) we get the exception 'Multiple constructors accepting all given argument types have been found in type'. We have a custom DbContext with multiple constructors.
Adding DbContextFactory
Custom DbContext
I have found the following issues regarding this: #24124
The person in said ticket seems to have found a solution using a design time factory. We tried to implement this as well, but this did not seem to have any effect.
All we had to do to implement the design time factory was just add this class in the same library as the DbContext, correct?
We noticed this issue should be fixed in the lastest daily build of .NET 6, but we cannot currently use .NET 6. Is there anything we are missing or can do in the meantime?
Include stack traces
Include provider and version information
EF Core version: 5.0.8
Database provider: Oracle.EntityFrameworkCore
Target framework: NET 5.0
Operating system: Windows 10
IDE: Visual Studio 2019 16.10
The text was updated successfully, but these errors were encountered: