UOW + Repository + Autofac加载两个不同的DbContext

2024-02-10

我今天遇到了一个问题,我无法解决它,我搜索了很多,但无法找到解决方案,如果可以的话请帮助我。

我正在实现一个 MVC 应用程序,它使用 EF + 存储库模式 + 工作单元和 Autofac 作为依赖注入器。

我能够使用一个 DbContext 类,但我面临着一种情况,我需要使用另一个 DbContext 实例(它使用另一个用户凭据访问另一个数据库)

让我更好地解释一下:我有来自数据库 A 的 EntityA (并且有一个 DatabaseA_Context 类)。所以我需要一个 EntityB,它来自数据库 B(具有自己的 DatabaseB_Context 类)。

当我使用 AutoFac 注册它们时,只有最后配置的依赖项会注入到 GenericRepository 实现中。

我已经找到文章说 Autofac 用最后一个值覆盖注册。

我已经找到了另一篇文章,其中显示如果我在 UnitOfWork 构造函数上传递 IEnumerable,我就可以看到它的所有注册类型,但我想要一个特定的类型。

我说得够清楚吗?

我的代码如下:

我的控制器:

public class MyController : Controller
{
    private readonly IBaseBLL<EntityA> _aBLL;
    private readonly IBaseBLL<EntityB> _bBll;

    public MyController(IBaseBLL<EntityA> aBLL, IBaseBLL<EntityB> bBLL)
    {
        _aBLL = aBLL;
        _bBLL = bBLL;
    }
}

我的业务层

public interface IBaseBLL<T> where T : class
{
    T Select(Expression<Func<T, bool>> predicate);
    T AddT entity);
    void Update(T entity);
    T Delete(T entity);
}

public class BaseBLL<T> : IBaseBLL<T> where T : class
{
    private readonly IUnitOfWork _uow;

    public BaseBLL(IUnitOfWork uow)
    {
        _uow = uow;
    }

    //implementation goes here...
}

我的 UOW 实施

public interface IUnitOfWork : IDisposable
{
    int SaveChanges();
    IGenericRepository<T> Repository<T>() where T : class;
}

public class UnitOfWork : IUnitOfWork
{
    private readonly DbContext _dbContext;
    private bool disposed = false;
    private Dictionary<Type, object> repositories;


    public UnitOfWork(DbContext dbContext)
    {
        _dbContext = dbContext;
        repositories = new Dictionary<Type, object>();
    }

    public IGenericReposity<T> Repository<T>() where T : class
    {
        if (repositories.Keys.Contains(typeof(T)))
            return repositories[typeof(T)] as IGenericReposity<T>;

        IGenericReposity<T> repository = new GenericRepository<T>(_dbContext);
        repositories.Add(typeof(T), repository );
        return repository ;
    }

    public int SaveChanges()
    {
        return _dbContext.SaveChanges();
    }

    protected virtual void Dispose(bool disposing)
    {
        if (!this.disposed)
            if (disposing)
                _dbContext.Dispose();

        this.disposed = true;
    }

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }
}

我的存储库实施

public class GenericRepository<T> : IGenericRepositoryT> where T : class
{
    protected readonly DbContext _dbContext;
    protected IDbSet<T> _dbSet;

    public GenericRepository(DbContext dbContext)
    {
        _dbContext = dbContext;
        _dbSet = _dbContext.Set<T>();
    }

    //implementation goes here...
}

我的 AutoFac 注册(在 Global.asax 文件中)

var builder = new ContainerBuilder();

builder.RegisterType(typeof(DatabaseA_Context)).As(typeof(DbContext)).InstancePerLifetimeScope();
builder.RegisterType(typeof(DatabaseB_Context)).As(typeof(DbContext)).InstancePerLifetimeScope();
builder.RegisterType(typeof(UnitOfWork)).As(typeof(IUnitOfWork)).InstancePerRequest(); 

请帮忙


你应该使用命名和密钥服务 http://docs.autofac.org/en/latest/advanced/keyed-services.html

builder.RegisterType<DatabaseA_Context>()
       .Named<DbContext>("databaseA")
       .InstancePerLifetimeScope();
builder.RegisterType<DatabaseB_Context>()
       .Named<DbContext>("databaseB")
       .InstancePerLifetimeScope();

然后您可以在注册时为组件指定所需的 DbContext

builder.RegisterType<MyService>()
       .As<IService>()
       .WithParameter((pi, c) => pi.Name == "dbContext", 
                      (pi, c) => c.ResolveNamed<DbContext>("databaseA"))

或者通过使用IIndex<,>

public class MyService : IService
{
    public MyService(IIndex<String, DbContext> dbContexts)
    {
        var databaseA = dbContexts["databaseA"];
    }
}

Autofac还支持指定命名注册WithKeyAttribute

public class MyService : IService
{
    public MyService([WithKey("DatabaseA")DbContext dbContext)
    {
    }
}

请参阅元数据文档 http://docs.autofac.org/en/latest/advanced/metadata.html有关如何获取的更多信息WithKeyAttribute set up.

有了这个解决方案,DbContext不会被注册。如果你想要默认值DbContext你可以像这样注册一个:

builder.Register(c => c.ResolveNamed<DbContext>("databaseA"))
       .As<DbContext>()
       .InstancePerLifetimeScope(); 

您还可以使用一个模块,该模块将根据参数名称选择正确的注册:

public class MyService : IService
{
    public MyService(DbContext dbContextA, DbContext dbContextB)
    {
    }
}

为此,您需要注册此Autofac Module

public class DbContextModule : Module
{
    protected override void AttachToComponentRegistration(
        IComponentRegistry componentRegistry, IComponentRegistration registration)
    {
        registration.Preparing += Registration_Preparing;
    }

    private void Registration_Preparing(Object sender, PreparingEventArgs e)
    {
        Parameter parameter = new ResolvedParameter(
                                (pi, c) => pi.ParameterType == typeof(DbContext),
                                (pi, c) =>
                                {
                                    if (pi.Name.Equals("dbContextA", StringComparison.OrdinalIgnoreCase))
                                    {
                                        return c.ResolveNamed<DbContext>("databaseA");
                                    }
                                    else if (pi.Name.Equals("dbContextB", StringComparison.OrdinalIgnoreCase))
                                    {
                                        return c.ResolveNamed<DbContext>("databaseB");
                                    }
                                    else
                                    {
                                        throw new NotSupportedException($"DbContext not found for '{pi.Name}' parameter name");
                                    }
                                });
        e.Parameters = e.Parameters.Concat(new Parameter[] { parameter });
    }
}

and

builder.RegisterModule<DbContextModule>()
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

UOW + Repository + Autofac加载两个不同的DbContext 的相关文章

  • 如何在 Cassandra 中存储无符号整数?

    我通过 Datastax 驱动程序在 Cassandra 中存储一些数据 并且需要存储无符号 16 位和 32 位整数 对于无符号 16 位整数 我可以轻松地将它们存储为有符号 32 位整数 并根据需要进行转换 然而 对于无符号 64 位整
  • std::vector 与 std::stack

    有什么区别std vector and std stack 显然 向量可以删除集合中的项目 尽管比列表慢得多 而堆栈被构建为仅后进先出的集合 然而 堆栈对于最终物品操作是否更快 它是链表还是动态重新分配的数组 我找不到关于堆栈的太多信息 但
  • free 和 malloc 在 C 中如何工作?

    我试图弄清楚如果我尝试 从中间 释放指针会发生什么 例如 看下面的代码 char ptr char malloc 10 sizeof char for char i 0 i lt 10 i ptr i i 10 ptr ptr ptr pt
  • -webkit-box-shadow 与 QtWebKit 模糊?

    当时有什么方法可以实现 webkit box shadow 的工作模糊吗 看完这篇评论错误报告 https bugs webkit org show bug cgi id 23291 我认识到这仍然是一个问题 尽管错误报告被标记为RESOL
  • 如何在 C++ 中标记字符串?

    Java有一个方便的分割方法 String str The quick brown fox String results str split 在 C 中是否有一种简单的方法可以做到这一点 The 增强分词器 http www boost o
  • 如何使从 C# 调用的 C(P/invoke)代码“线程安全”

    我有一些简单的 C 代码 它使用单个全局变量 显然这不是线程安全的 所以当我使用 P invoke 从 C 中的多个线程调用它时 事情就搞砸了 如何为每个线程单独导入此函数 或使其线程安全 我尝试声明变量 declspec thread 但
  • C# 列表通用扩展方法与非通用扩展方法

    这是一个简单的问题 我希望 集合类中有通用和非通用方法 例如List
  • 在 Unity 中实现 Fur with Shells 技术

    我正在尝试在 Unity 中实现皮毛贝壳技术 http developer download nvidia com SDK 10 5 direct3d Source Fur doc FurShellsAndFins pdf Fins 技术被
  • 使用 C# 中的 CsvHelper 将不同文化的 csv 解析为十进制

    C 中 CsvHelper 解析小数的问题 我创建了一个从 byte 而不是文件获取 csv 文件的类 并且它工作正常 public static List
  • 两个类可以使用 C++ 互相查看吗?

    所以我有一个 A 类 我想在其中调用一些 B 类函数 所以我包括 b h 但是 在 B 类中 我想调用 A 类函数 如果我包含 a h 它最终会陷入无限循环 对吗 我能做什么呢 仅将成员函数声明放在头文件 h 中 并将成员函数定义放在实现文
  • C 编程:带有数组的函数

    我正在尝试编写一个函数 该函数查找行为 4 列为 4 的二维数组中的最大值 其中二维数组填充有用户输入 我知道我的主要错误是函数中的数组 但我不确定它是什么 如果有人能够找到我出错的地方而不是编写新代码 我将不胜感激 除非我刚去南方 我的尝
  • 为什么使用小于 32 位的整数?

    我总是喜欢使用最小尺寸的变量 这样效果就很好 但是如果我使用短字节整数而不是整数 并且内存是 32 位字可寻址 这真的会给我带来好处吗 编译器是否会做一些事情来增强内存使用 对于局部变量 它可能没有多大意义 但是在具有数千甚至数百万项的结构
  • 如何在 Android 中使用 C# 生成的 RSA 公钥?

    我想在无法假定 HTTPS 可用的情况下确保 Android 应用程序和 C ASP NET 服务器之间的消息隐私 我想使用 RSA 来加密 Android 设备首次联系服务器时传输的对称密钥 RSA密钥对已在服务器上生成 私钥保存在服务器
  • 在 WPF 中使用 ReactiveUI 提供长时间运行命令反馈的正确方法

    我有一个 C WPF NET 4 5 应用程序 用户将用它来打开某些文件 然后 应用程序将经历很多动作 读取文件 通过许多插件和解析器传递它 这些文件可能相当大 gt 100MB 因此这可能需要一段时间 我想让用户了解 UI 中发生的情况
  • C++ 继承的内存布局

    如果我有两个类 一个类继承另一个类 并且子类仅包含函数 那么这两个类的内存布局是否相同 e g class Base int a b c class Derived public Base only functions 我读过编译器无法对数
  • 当文件流没有新数据时如何防止fgets阻塞

    我有一个popen 执行的函数tail f sometextfile 只要文件流中有数据显然我就可以通过fgets 现在 如果没有新数据来自尾部 fgets 挂起 我试过ferror and feof 无济于事 我怎样才能确定fgets 当
  • C# 中最小化字符串长度

    我想减少字符串的长度 喜欢 这串 string foo Lorem ipsum dolor sit amet consectetur adipiscing elit Aenean in vehicula nulla Phasellus li
  • 为什么 std::uint32_t 与 uint32_t 不同?

    我对 C 有点陌生 我有一个编码作业 很多文件已经完成 但我注意到 VS2012 似乎有以下语句的问题 typedef std uint32 t identifier 不过 似乎将其更改为 typedef uint32 t identifi
  • Mono 应用程序在非阻塞套接字发送时冻结

    我在 debian 9 上的 mono 下运行一个服务器应用程序 大约有 1000 2000 个客户端连接 并且应用程序经常冻结 CPU 使用率达到 100 我执行 kill QUIT pid 来获取线程堆栈转储 但它总是卡在这个位置
  • 现代编译器是否优化乘以 1 和 -1

    如果我写 template

随机推荐

  • 如何以八度增加命令窗口的字体大小

    我试图弄清楚如何增加命令窗口文本 我想通了legend legend fontsize 10 Low fontsize 10 Medium fontsize 10 High 我尝试做同样的事情 但是command command windo
  • 谷歌地图无法正确呈现

    我正在使用主干和 gmaps js 由于某种原因 地图无法正确渲染 控制器没有正确显示 信息窗口的渲染也很奇怪 我正在使用gmaps js 库 https github com HPNeo gmaps 我什至不知道如何调试这个东西 这是我的
  • 计数信号量和二进制信号量之间的区别

    计数和二进制信号量有什么区别 我在某处看到的是 两者都可以控制 N 个请求资源的进程 两者都拥有自由邦 二进制信号量和计数信号量可以保护的资源数量是否有限制 两者都只允许一个进程一次使用一种资源 还有其他区别吗 上述属性是否正确 实际上 这
  • python语法错误无效语法[重复]

    这个问题在这里已经有答案了 我是 Python 编程语言的新手 我买了一本书并且一直在读 这本书的名字是 3x Python 初学者编程第三版 我正在努力将迄今为止所学到的知识付诸实践 我有一个我不明白的问题 我知道它很简单 但我不确定如何
  • 如何在 SQLAlchemy for MSSQL 中设置架构?

    我目前这样做 usr bin env python 3rd party modules from sqlalchemy import create engine requires pymssql local modules from con
  • 如何尽可能快地将大量记录插入MySql数据库

    我有一个如下所示的数据库表 create table temperature id int unsigned not null auto increment primary key temperature double 在我的程序中 我将大
  • 从 Xamarin.Forms 应用程序打印

    我是 Xamarin 新手 目前正在使用 Xamarin Forms 开发示例或 概念证明 应用程序 我应该从这个应用程序执行打印任务 尽管我现在还不确定要打印什么 屏幕 标签内容 文件等 无论哪种方式 从 Xamarin Forms 应用
  • 使用来自互联网的图像更新 Android 小部件(使用异步任务)

    我有一个简单的 Android 小部件 我想用互联网上的图像进行更新 我可以在小部件上显示静态图像 没有问题 有人告诉我 您需要为此使用异步任务 而我对此没有太多经验 这是我的小部件 Override public void onUpdat
  • Docker Rancher - 从 WSL 使用 docker 时权限被拒绝

    我已经在 Windows 10 上使用 dockerd 选项安装了 Docker Rancher 并为我当前的 WSL 发行版 Ubuntu 安装了 WSL 当我尝试在 WSL2 中使用 docker 时 出现以下错误 fpapi xxx
  • Java 中 int 转换为数组 char

    我试图在不使用字符串操作的情况下将整数转换为字符数组 我的尝试是 int number 12 char test Character toChars number for char c test System out println c 没
  • 在多对多关系上添加元素

    我正在做一个项目 从学校的角度 你可以计算每个学生的平均值 您可以在一个屏幕上注册学生 第一个实体 在另一个屏幕上注册科目 第二个实体 学生有姓名 电子邮件 成绩和平均分作为属性 科目有姓名 它们彼此之间是多对多关联的 我正在尝试为每个学生
  • UITableView 和单元格重用

    我有一个UITableView我已经子类化了UITableViewCell 叫它CustomCell 所以它有几个标签和一个UIImageView 只有某些单元格才会真正显示图像 这是我的代码tableView cellForRowAtIn
  • 如何获取AVPlayer的视频帧?

    我有 PlayerView 类用于显示 AVPlayer 的播放 代码来自文档 https developer apple com library archive documentation AudioVideo Conceptual AV
  • 来自 StringIO 源的 Python xml etree DTD?

    我正在调整以下代码 通过中的建议创建这个问题 https stackoverflow com questions 2835077 lxml unicode entity parse problems 它采用 XML 文件及其 DTD 并将它
  • 在 Vista 上安装后无法使用 gem 和 ruby​​ 命令

    我昨天按照此站点上的说明在 Vista 32 位上安装了 Ruby 和 Ruby on Rails http rubyonrails org down http rubyonrails org down 所以我下载了安装程序 然后是 Gem
  • 当数据量较小时,node.js response.write(data) 需要很长时间

    我注意到 Node js 中以下代码的性能出现了奇怪的行为 当尺寸为content为1 4KB 请求的响应时间大约为16ms 然而 当尺寸为content只有988字节 请求的响应时间奇怪地长得多 大致200ms response writ
  • AngularJS - ngSwitch 和 ng Click 在 ng Repeat 中不起作用

    我想显示列表的元素 这要归功于ngSwitch但我不知道该怎么做ngRepeat 我一开始没有列出清单 只是为了了解如何ngSwitch工作并向您展示我想要做什么 这里有一个 jsFiddle 可以帮助您理解 jdFiffle 1 http
  • 在 RStudio 中记录 R 包中的 R6 类和方法

    我正在努力处理 R6 类及其方法的文档 我的目标是在 RStudio 中获得方法的自动完成功能 目前 我只得到方法的名称 但没有得到我通常使用的帮助信息roxygen2用参数等记录函数 目前 这是我的班级 importFrom R6 R6C
  • NativeScript 与 Flutter [关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 我已经开始工作Nativescript 与 Angular https www nativescript org 最好的部分是代码共享技术 我可
  • UOW + Repository + Autofac加载两个不同的DbContext

    我今天遇到了一个问题 我无法解决它 我搜索了很多 但无法找到解决方案 如果可以的话请帮助我 我正在实现一个 MVC 应用程序 它使用 EF 存储库模式 工作单元和 Autofac 作为依赖注入器 我能够使用一个 DbContext 类 但我