C# - 如何使用 Autofac return 不同的 SqlConnection 实例
C# - How to return different instances of SqlConnection using Autofac
我有两个数据库:DbX 和 DbY。我必须从 DbX 获取数据,对其进行处理并将其保存到 DbY。由于两者的模型相同,我创建了抽象 SqlDataAccess class,如下所示:
public abstract class SqlDataAccess : IDataAccess
{
protected readonly IDbConnection _connection;
protected SqlDataAccess(IDbConnection connection)
{
_connection = connection;
}
public virtual long Add<ModelType>(ModelType model) where ModelType : class
{
_connection.Open();
var output = _connection.Insert(model);
_connection.Close();
return output;
}
public virtual ICollection<ModelType> Get<ModelType>(string sql, DynamicParameters parameters = null, Tenant tenant = null) where ModelType : class
{
_connection.Open();
if (tenant != null) _connection.ChangeDatabase(tenant.DbName);
var output = _connection.Query<ModelType>(sql, parameters).ToList();
_connection.Close();
return output;
}
public bool Update<ModelType>(ModelType model) where ModelType : class
{
_connection.Open();
var output = _connection.Update(model);
_connection.Close();
return output;
}
public bool Delete<ModelType>(ModelType model) where ModelType : class
{
_connection.Open();
var output = _connection.Delete(model);
_connection.Close();
return output;
}
}
我还有 XDataAccess、YDataAccess 和它们的接口:
public interface IXDataAccess: IDataAccess
{
}
public interface IYDataAccess: IDataAccess
{
}
我还创建了 IXDbConnection 和 IYDbConnection。
public interface IXDbConnection: IDbConnection
{
}
public interface IYDbConnection: IDbConnection
{
}
所以我最终得到:
public class XDataAccess : SqlDataAccess, IXDataAccess
{
public XDataAccess(IXDbConnection connection)
: base(connection)
{
}
}
public class YDataAccess : SqlDataAccess, IYDataAccess
{
public YDataAccess(IYDbConnection connection)
: base(connection)
{
}
}
我想在这样的服务中使用它:
public class AccountService : IAccountService
{
private readonly IXDataAccess _xDataAccess;
private readonly IYAccess _yDataAccess;
public AccountService(IXDataAccess xDataAccess, IYDataAccess yDataAccess)
{
_xDataAccess = xDataAccess;
_yDataAccess = yDataAccess;
}
public ICollection<Account> GetFromDbX(DateTime time, Tenant tenant)
{
DynamicParameters parameters = new DynamicParameters();
parameters.Add("@SomeParameter", time);
string sql = $@"SELECT * FROM Accounts WHERE SomeParameter = @SomeParameter";
var output = _xDataAccess.Get<Account>(sql, parameters, tenant);
return output;
}
public ICollection<Account> GetFromDbY(DateTime time)
{
DynamicParameters parameters = new DynamicParameters();
parameters.Add("@SomeParameter", time);
string sql = $@"SELECT * FROM Accounts WHERE SomeParameter = @SomeParameter";
var output = _yDataAccess.Get<Account>(sql, parameters);
return output;
}
}
现在,当我尝试在 Autofac 中注册所有内容时
builder.RegisterType<AccountService>().As<IAccountService>();
builder.RegisterType<XDataAccess>().As<IXDataAccess>();
builder.RegisterType<YDataAccess>().As<IYDataAccess>();
builder.Register(c => ConnectionFactory.Create("DbX")).As<IXDbConnection>();
builder.Register(c => ConnectionFactory.Create("DbY")).As<IYDbConnection>();
我收到此错误:System.ArgumentException:“类型 'System.Data.IDbConnection' 无法分配给服务 'SomeNamespace.DataAccess.IXDbConnection'。
ConnectionFactory.Create() returns SqlConnection.
它有可能工作还是我做错了什么?
有更好的方法吗?
您不能注册未实现的接口。我可以建议你一个解决方案。
更改 DataAccess
类 的构造函数,期望 IDbConnecttion
public class XDataAccess : SqlDataAccess, IXDataAccess
{
public XDataAccess(IDbConnection connection)
: base(connection)
{
}
}
public class YDataAccess : SqlDataAccess, IYDataAccess
{
public YDataAccess(IDbConnection connection)
: base(connection)
{
}
}
然后注册他们创建新的实例。你不需要 IXDbConnection
和 IYDbConnection
.
builder.RegisterType<AccountService>().As<IAccountService>();
builder.Register(c => new XDataAccess(ConnectionFactory.Create("DbX"))).As<IXDataAccess>();
builder.Register(c => new YDataAccess(ConnectionFactory.Create("DbY"))).As<IYDataAccess>();
我有两个数据库:DbX 和 DbY。我必须从 DbX 获取数据,对其进行处理并将其保存到 DbY。由于两者的模型相同,我创建了抽象 SqlDataAccess class,如下所示:
public abstract class SqlDataAccess : IDataAccess
{
protected readonly IDbConnection _connection;
protected SqlDataAccess(IDbConnection connection)
{
_connection = connection;
}
public virtual long Add<ModelType>(ModelType model) where ModelType : class
{
_connection.Open();
var output = _connection.Insert(model);
_connection.Close();
return output;
}
public virtual ICollection<ModelType> Get<ModelType>(string sql, DynamicParameters parameters = null, Tenant tenant = null) where ModelType : class
{
_connection.Open();
if (tenant != null) _connection.ChangeDatabase(tenant.DbName);
var output = _connection.Query<ModelType>(sql, parameters).ToList();
_connection.Close();
return output;
}
public bool Update<ModelType>(ModelType model) where ModelType : class
{
_connection.Open();
var output = _connection.Update(model);
_connection.Close();
return output;
}
public bool Delete<ModelType>(ModelType model) where ModelType : class
{
_connection.Open();
var output = _connection.Delete(model);
_connection.Close();
return output;
}
}
我还有 XDataAccess、YDataAccess 和它们的接口:
public interface IXDataAccess: IDataAccess
{
}
public interface IYDataAccess: IDataAccess
{
}
我还创建了 IXDbConnection 和 IYDbConnection。
public interface IXDbConnection: IDbConnection
{
}
public interface IYDbConnection: IDbConnection
{
}
所以我最终得到:
public class XDataAccess : SqlDataAccess, IXDataAccess
{
public XDataAccess(IXDbConnection connection)
: base(connection)
{
}
}
public class YDataAccess : SqlDataAccess, IYDataAccess
{
public YDataAccess(IYDbConnection connection)
: base(connection)
{
}
}
我想在这样的服务中使用它:
public class AccountService : IAccountService
{
private readonly IXDataAccess _xDataAccess;
private readonly IYAccess _yDataAccess;
public AccountService(IXDataAccess xDataAccess, IYDataAccess yDataAccess)
{
_xDataAccess = xDataAccess;
_yDataAccess = yDataAccess;
}
public ICollection<Account> GetFromDbX(DateTime time, Tenant tenant)
{
DynamicParameters parameters = new DynamicParameters();
parameters.Add("@SomeParameter", time);
string sql = $@"SELECT * FROM Accounts WHERE SomeParameter = @SomeParameter";
var output = _xDataAccess.Get<Account>(sql, parameters, tenant);
return output;
}
public ICollection<Account> GetFromDbY(DateTime time)
{
DynamicParameters parameters = new DynamicParameters();
parameters.Add("@SomeParameter", time);
string sql = $@"SELECT * FROM Accounts WHERE SomeParameter = @SomeParameter";
var output = _yDataAccess.Get<Account>(sql, parameters);
return output;
}
}
现在,当我尝试在 Autofac 中注册所有内容时
builder.RegisterType<AccountService>().As<IAccountService>();
builder.RegisterType<XDataAccess>().As<IXDataAccess>();
builder.RegisterType<YDataAccess>().As<IYDataAccess>();
builder.Register(c => ConnectionFactory.Create("DbX")).As<IXDbConnection>();
builder.Register(c => ConnectionFactory.Create("DbY")).As<IYDbConnection>();
我收到此错误:System.ArgumentException:“类型 'System.Data.IDbConnection' 无法分配给服务 'SomeNamespace.DataAccess.IXDbConnection'。
ConnectionFactory.Create() returns SqlConnection.
它有可能工作还是我做错了什么? 有更好的方法吗?
您不能注册未实现的接口。我可以建议你一个解决方案。
更改 DataAccess
类 的构造函数,期望 IDbConnecttion
public class XDataAccess : SqlDataAccess, IXDataAccess
{
public XDataAccess(IDbConnection connection)
: base(connection)
{
}
}
public class YDataAccess : SqlDataAccess, IYDataAccess
{
public YDataAccess(IDbConnection connection)
: base(connection)
{
}
}
然后注册他们创建新的实例。你不需要 IXDbConnection
和 IYDbConnection
.
builder.RegisterType<AccountService>().As<IAccountService>();
builder.Register(c => new XDataAccess(ConnectionFactory.Create("DbX"))).As<IXDataAccess>();
builder.Register(c => new YDataAccess(ConnectionFactory.Create("DbY"))).As<IYDataAccess>();