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
的新实例,您可以将 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;
}
}
}
有关详细信息,请参阅 Autofac 文档中的 Combining Owned
with Func
。
我们正在为数据库使用 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
的新实例,您可以将 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;
}
}
}
有关详细信息,请参阅 Autofac 文档中的 Combining Owned
with Func
。