You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Xamarin Forms中Autofac注入双SQLite连接的仓储问题排查

解决Autofac注入双SQLite连接与仓储区分的问题

你的问题核心出在两个地方:双SQLite连接的歧义注册,以及抽象仓储类的错误注册方式。下面一步步帮你修正:

1. 给两个SQLite连接做命名区分

Autofac默认会覆盖同类型的重复注册(或抛出歧义错误),所以得给两个SQLiteAsyncConnection加上唯一标识,用Named方法实现命名注册:

// 注册第一个数据库连接,命名为"FirstDb"
builder.Register(c => new SQLiteAsyncConnection(c.Resolve<IDatabaseConfiguration>().GetFirstConnectionPath()))
       .Named<SQLiteAsyncConnection>("FirstDb")
       .SingleInstance();

// 注册第二个数据库连接,命名为"SecondDb"
builder.Register(c => new SQLiteAsyncConnection(c.Resolve<IDatabaseConfiguration>().GetSecondConnectionPath()))
       .Named<SQLiteAsyncConnection>("SecondDb")
       .SingleInstance();

2. 注册具体仓储类而非抽象类

你之前注册抽象的BaseRepository<>是完全错误的——抽象类无法被实例化,Autofac根本没法创建它的实例。应该直接注册你写的两个具体仓储SQLiteRepositoryFirst<>和SQLiteRepositorySecond<>,同时绑定它们对应的命名数据库连接:

// 注册第一个仓储,绑定"FirstDb"连接
builder.RegisterGeneric(typeof(SQLiteRepositoryFirst<>))
       .AsImplementedInterfaces()
       // 告诉Autofac:当构造函数需要SQLiteAsyncConnection时,解析命名为"FirstDb"的实例
       .WithParameter(
           (pi, ctx) => pi.ParameterType == typeof(SQLiteAsyncConnection),
           (pi, ctx) => ctx.ResolveNamed<SQLiteAsyncConnection>("FirstDb")
       )
       // 给这个仓储实例也加个命名,方便后续注入区分
       .Named<IRepository<>>("FirstRepository")
       .SingleInstance();

// 注册第二个仓储,绑定"SecondDb"连接
builder.RegisterGeneric(typeof(SQLiteRepositorySecond<>))
       .AsImplementedInterfaces()
       .WithParameter(
           (pi, ctx) => pi.ParameterType == typeof(SQLiteAsyncConnection),
           (pi, ctx) => ctx.ResolveNamed<SQLiteAsyncConnection>("SecondDb")
       )
       .Named<IRepository<>>("SecondRepository")
       .SingleInstance();

3. 使用时明确指定要注入的仓储

现在你在ViewModel或其他类中需要使用IRepository<HouseEntity>时,通过[Named]特性告诉Autofac要哪个实例:

public class HouseManagementViewModel
{
    private readonly IRepository<HouseEntity> _firstHouseRepo;
    private readonly IRepository<HouseEntity> _secondHouseRepo;

    // 构造函数注入时,用Named特性区分两个仓储
    public HouseManagementViewModel(
        [Named("FirstRepository")] IRepository<HouseEntity> firstHouseRepo,
        [Named("SecondRepository")] IRepository<HouseEntity> secondHouseRepo
    )
    {
        _firstHouseRepo = firstHouseRepo;
        _secondHouseRepo = secondHouseRepo;
    }

    // 示例:用第一个仓储添加数据
    public async Task AddHouseToFirstDb(HouseEntity house)
    {
        await _firstHouseRepo.AddAsync(house);
    }
}

如果是直接从容器解析,也可以用命名解析:

var firstHouseRepo = container.ResolveNamed<IRepository<HouseEntity>>("FirstRepository");

为什么之前的配置会出问题?

  • 双连接歧义:你注册了两个同类型的SQLiteAsyncConnection,Autofac不知道该选哪个,默认只会保留最后一个注册的实例,导致所有仓储都用同一个数据库。
  • 抽象类注册错误:BaseRepository<>是抽象类,Autofac无法实例化它,你的注册本身就是无效的,必须注册具体的实现类(也就是你写的两个SQLiteRepository)。

内容的提问来源于stack exchange,提问作者fandro

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 07:14:27