autofac 两个pgsql数据库连接

Autofac two pgsql database connections

我们正在为数据库使用 InstancePerLifetimeScope。但在某些情况下,我们需要一个新的数据库连接。 我们的 autofac 注册是

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 { }

我们在 运行 此代码

时遇到错误

An exception of type 'System.ArgumentException' occurred in Autofac.dll but was not handled in user code: 'The type 'Npgsql.NpgsqlConnection' is not assignable to service 'xxxx.Core.Data.IDpNewDb'.'

有什么想法吗?

编辑 : 应用精简版代码下方

我的创业公司Class

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 ();
    }
}

Autofac 模块

 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) {

        }
    }
}

下面一行行不通

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

NpgsqlConnection 未实现 IDpNewDb。即使使用纯 C#,您也会遇到类似的错误。

如果您想要 IDbConnection 的新实例,您可以将 OwnedFunc<> 结合使用,这将像一个迷你范围一样,您将随时拥有一个新实例。


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;
        }
    }
}

有关详细信息,请参阅 Autofac 文档中的 Combining Owned with Func