web-dev-qa-db-fra.com

AutoFac/.NET Core - Enregistrer DBcontext

J'ai un nouveau projet .NET Core API Web qui a la structure de projets suivante:

API -> Commerce/Domaine -> Infrastructure

L'API est très mince avec seulement les méthodes de l'API. La couche Business/Domain a toute ma logique métier. Enfin, ma couche d'infrastructure contient des classes de base de données utilisant EF Core 2.0.

Je sais utiliser l’injection de dépendances intégrée dans .NET Core. Je peux ajouter une référence du projet API au projet Infrastructure, puis ajouter le code suivant dans le fichier StartUp.cs:

services.AddDbContext<MyContext>(options => options.UseSqlServer(connectionString));

Cependant, je voudrais maintenir une séparation plus traditionnelle des préoccupations. Jusqu'à présent, j'ai ajouté un module dans ma couche d'infrastructure qui tente d'effectuer l'enregistrement de la manière suivante:

builder.Register(c =>
        {
            var config = c.Resolve<IConfiguration>();

            var opt = new DbContextOptionsBuilder<MyContext>();
            opt.UseSqlServer(config.GetSection("ConnectionStrings:MyConnection:ConnectionString").Value);

            return new MyContext(opt.Options);
        }).AsImplementedInterfaces().InstancePerLifetimeScope();

Le DBContext, cependant, n'est pas enregistré. Toute classe qui tente d'accéder au DBContext injecté ne peut pas résoudre le paramètre. 

Est-il possible d'inscrire le DBContext dans un projet séparé en utilisant AuftoFac dans un projet d'API Web .NET Core?

7
Kyle Barnes

Je pense que le problème est que vous essayez d’enregistrer MyContext() en utilisant AsImplementedInterfaces(). Ce n’est pas ainsi que DbContext est généralement enregistré. Vous devez vous inscrire et résoudre la classe elle-même.

6

J'utilise Autofac pour enregistrer à la fois HttpContextAccessor et DbContext.

builder.RegisterType<HttpContextAccessor>().As<IHttpContextAccessor>().SingleInstance();

builder
    .RegisterType<AppDbContext>()
    .WithParameter("options", DbContextOptionsFactory.Get())
    .InstancePerLifetimeScope();

DbContextOptionsFactory

public class DbContextOptionsFactory
{
    public static DbContextOptions<AppDbContext> Get()
    {
        var configuration = AppConfigurations.Get(WebContentDirectoryFinder.CalculateContentRootFolder());

        var builder = new DbContextOptionsBuilder<AppDbContext>();
        DbContextConfigurer.Configure(builder, configuration.GetConnectionString(AppConsts.ConnectionStringName));

        return builder.Options;
    }
}

DbContextConfigurer

public class DbContextConfigurer
{
    public static void Configure(DbContextOptionsBuilder<AppDbContext> builder, string connectionString)
    {
        builder.UseNpgsql(connectionString).UseLazyLoadingProxies();
    }
}
8
Alex Herman

Une autre solution simple pour Autofac version 4.8.1

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddMvc().AddControllersAsServices();

        services.AddDbContext<MyContext>(options => options.UseSqlServer(Configuration.GetConnectionString("ConnectionStrings:MyConnection:ConnectionString")));

        var builder = new ContainerBuilder();

        builder.Populate(services);

        //...
        // Your interface registration
        //...

        builder.Build(Autofac.Builder.ContainerBuildOptions.None);
    }
1
Çağlar Duman

Dans le projet souhaité, vous pouvez créer une méthode d'extension qui ajoute le contexte à la collection. 

public static class MyDataExtensions {
    public static IServiceCollection AddMyData(this IServiceCollection services) {
        //...

        services.AddDbContext<MyContext>(options => options.UseSqlServer(connectionString));

        //...
    }
}

avec cela alors dans votre démarrage il est juste une question d'appeler l'extension exposée de l'autre projet

services.AddMyData();

//...other settings

Le projet API est la racine de la composition. Il doit donc connaître toutes les dépendances pertinentes. Au moins avec cette extension, vous n’avez pas à faire de référence directe au contexte de base de données utilisé,

1
Nkosi