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

然后注册他们创建新的实例。你不需要 IXDbConnectionIYDbConnection.

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