Autofa c два pg sql подключения к базе данных - PullRequest
0 голосов
/ 06 марта 2020

Мы используем InstancePerLifetimeScope для базы данных. Но в некоторых случаях нам нужно новое соединение с БД. Наша авторизация c зарегистрирована

builder.RegisterType<Npgsql.NpgsqlConnection> ()
     As<IDbConnection> ()
     .WithParameter ("connectionString", constr)
     .InstancePerLifetimeScope ();

 // for NewDb Connection     
 builder.RegisterType<Npgsql.NpgsqlConnection> ()
      .As<IDpNewDb> ()
      .WithParameter ("connectionString", constr)
      .InstancePerRequest ();   

Код для IDpNewDb:

public interface IDpNewDb : IDbConnection { }

При выполнении этого кода возникает ошибка

Исключение типа 'System.ArgumentException' произошло в Autofa c .dll, но не было обработано в коде пользователя: 'Тип' Npg sql .NpgsqlConnection 'не может быть назначен службе' xxxx.Core.Data. .IDpNewDb '.'

Есть идеи?

Редактировать : ниже приведен код для урезанной версии приложения

My Класс запуска

public class Startup {
    public Startup (IConfiguration configuration) {
        Configuration = configuration;
    }
    public IConfiguration Configuration { get; }
    public void ConfigureServices (IServiceCollection services) {
        services.AddMvc ().SetCompatibilityVersion (CompatibilityVersion.Version_2_2);
        ConfigureAutofac (services);
    }
    internal static AutofacServiceProvider ConfigureAutofac (IServiceCollection services) {

        var containerBuilder = new ContainerBuilder ();

        containerBuilder.RegisterModule<DefaultModule> ();
        containerBuilder.Populate (services);
        var container = containerBuilder.Build ();
        var srv = new AutofacServiceProvider (container);
        return srv;
    }
    public void Configure (IApplicationBuilder app, IHostingEnvironment env) {
        if (env.IsDevelopment ()) {
            app.UseDeveloperExceptionPage ();
        } else {
            app.UseHsts ();
        }

        app.UseHttpsRedirection ();
        app.UseMvc ();
    }
}

Autofa c Модуль

 internal class DefaultModule : Autofac.Module {
        public void init (ContainerBuilder builder) {
            Load (builder);
        }

        protected override void Load (ContainerBuilder builder) {
            builder.RegisterType<Npgsql.NpgsqlConnection> ()
                .As<IDbConnection> ()
                .WithParameter ("connectionString", "Server=localhost;Database=DBName;User Id=postgres;password=*******;Application Name=myapp;")
                .InstancePerLifetimeScope ();

            builder.RegisterType<Npgsql.NpgsqlConnection> ()
                .As<IDbNewDb> ()
                .WithParameter ("connectionString", "Server=localhost;Database=DBName;User Id=postgres;password=******;Application Name=myapp;")
                .InstancePerRequest ();
        }

    }

interfaces.cs

namespace autofac_issue {
        public interface IDbNewDb : IDbConnection { };
}

Наконец, контроллер

namespace autofac_issue.Controllers {
    [Route ("api/[controller]")]
    [ApiController]
    public class ValuesController : ControllerBase {
        // GET api/values
        public ValuesController (IDbNewDb dbnew, IDbConnection db) {

        }
    }
}

1 Ответ

2 голосов
/ 07 марта 2020

Следующая строка не будет работать

 builder.RegisterType<Npgsql.NpgsqlConnection> ()
        .As<IDpNewDb> ()

NpgsqlConnection не реализует IDpNewDb. У вас будет похожая ошибка даже при использовании чистого C#.

Если вы хотите новый экземпляр IDbConnection, вы можете использовать Owned в сочетании с Func<>, который будет действовать как мини-область, и у вас будет новый экземпляр в любое время.


public class X {
    public X(Func<Owned<IDbConnection>> dbConnectionFactory){
        this._dbConnectionFactory = dbConnectionFactory;
    }

    private readonly Func<Owned<IDbConnection>> _dbConnectionFactory; 

    public void Do(){
        // will create a new instance each time you call the factory 
        using(Owned<IDbConnection> ownedDbConnection = this._dbConnectionFactory()){
            IDbConnection dbConnection = ownedDbConnection.Value;
        }
    }
}

См. Объединение Owned с Func из документации Autofa c для получения дополнительной информации.

...