Warum sagt EF7, dass ich keine Provider konfiguriert habe, wenn ASP.net Identity mit demselben DbContext funktioniert?

asp.net-core c# ef-code-first entity-framework-core

Frage

Ich habe gerade angefangen, an einem experimentellen Projekt mit ASP.net 5, MVC6 und Entity Framework 7 zu arbeiten. Ich habe ASP.Net Identity funktioniert gut, aber dann versucht, einige meiner eigenen Daten zu dem DbContext hinzuzufügen und dieses Problem zu treffen. EF7 berichtet:

Während der Verarbeitung der Anforderung ist eine nicht behandelte Ausnahme aufgetreten.

InvalidOperationException: Es sind keine Datenbankanbieter konfiguriert. Konfigurieren Sie einen Datenbankanbieter durch Überschreiben von OnConfiguring in Ihrer DbContext-Klasse oder in der AddDbContext-Methode beim Einrichten von Diensten.

Microsoft.Data.Entity.Internal.DatabaseProviderSelector.SelectServices (ServiceProviderSource providerSource) Stack-Abfrage-Cookie-Header

InvalidOperationException: Es sind keine Datenbankanbieter konfiguriert. Konfigurieren Sie einen Datenbankanbieter durch Überschreiben von OnConfiguring in Ihrer DbContext-Klasse oder in der AddDbContext-Methode beim Einrichten von Diensten.

Hier ist meine Konfigurationsmethode:

    public void ConfigureServices(IServiceCollection services)
    {
        // Add framework services.
        services.AddApplicationInsightsTelemetry(Configuration);

        services.AddEntityFramework()
            .AddSqlServer()
            .AddDbContext<ApplicationDbContext>(options =>
                options.UseSqlServer(Configuration["Data:DefaultConnection:ConnectionString"]));

        services.AddIdentity<ApplicationUser, IdentityRole>()
            .AddEntityFrameworkStores<ApplicationDbContext>()
            .AddDefaultTokenProviders();

        services.AddMvc();

        // Add application services.
        services.AddTransient<IEmailSender, AuthMessageSender>();
        services.AddTransient<ISmsSender, AuthMessageSender>();

        services.AddTransient<ApplicationUnitOfWork>(instance => new ApplicationUnitOfWork());
    }

ApplicationUnitOfWork ist eine Fassade über EF7, um die enge Kopplung zu reduzieren. Hier ist das ganze bisher:

public class ApplicationUnitOfWork : IUnitOfWork
    {
    readonly ApplicationDbContext dbContext;

    public ApplicationUnitOfWork()
        {
        dbContext = new ApplicationDbContext();
        Products = new ProductRepository(dbContext);
        }

    public void Dispose() { dbContext.Dispose(); }

    public IUserRepository Users { get; }

    public IRepository<SoftwareProduct> Products { get; }

    public async Task CommitAsync() { await dbContext.SaveChangesAsync(); }

    public void Cancel() { throw new NotImplementedException(); }
    }

Jetzt, wenn ich die Webanwendung ausführe, kann ich ein Benutzerkonto registrieren und mich anmelden. EF erstellt die Datenbank, erstellt die Identitätstabellen und füllt sie mit Benutzerdaten. Die Produkttabelle wird ebenfalls erstellt - EF kann den ApplicationDbContext also eindeutig auf einer bestimmten Ebene verwenden und einen Provider finden, mit dem er die Datenbank und das Schema erstellt.

Wenn ich jedoch versuche, auf meinen Produkt-Controller zuzugreifen, der das ProductsRepository , beschwert sich EF - obwohl ApplicationDbContext in beiden Fällen verwendet wird und zum Erstellen der Datenbank verwendet wurde!

Wie kommt es? Was ist das Besondere an ASP.net Identity, dass es irgendwie einen Provider bekommen kann, aber meinen eigenen Code nicht? Welche "magische Beschwörung" vermisse ich?

Akzeptierte Antwort

Es ist, weil Sie es neu erfinden, anstatt es für Sie injiziert zu haben. Die neue Version wurde nicht konfiguriert. Sie sollten Ihre Klasse ändern, damit sie in den Konstruktor übernommen wird.

DbContext hat mehr als einen Konstruktor und Sie verwenden den leeren, der ihn nicht konfiguriert.

Besser lassen Sie es injizieren, indem Sie Ihren Konstruktor so machen:

 public ApplicationUnitOfWork(ApplicationDbContext context)
 {
    dbContext = context;
    Products = new ProductRepository(dbContext);
 }

Ihr Code zeigt, dass ApplicationDbContext bei der DI registriert wurde, Identität verwendet die injizierte, aber Sie sind nicht, seit Sie es mit dem parameterlosen Konstruktor selbst erstellt haben

Sie sollten Ihr ApplicationUnitOfWork auch registrieren, damit es injiziert werden kann:

services.AddScoped<ApplicationUnitOfWork, ApplicationUnitOfWork>();


Related

Lizenziert unter: CC-BY-SA with attribution
Nicht verbunden mit Stack Overflow
Lizenziert unter: CC-BY-SA with attribution
Nicht verbunden mit Stack Overflow