注入存储库上的 IDisposable

2024-01-16

我有以下 ADO .Net 存储库

public class Repository : IRepository, IDisposable
{
   private readonly IUnitOfWork UnitOfWork;
   private SqlConnection Connection;

   public Repository(IUnitOfWork unitOfWork, connectionString)
   {
      UnitOfWork = unitOfWork;
      Connection = new SqlConnection(connectionString);
      Connection.Open();
   }

   public MyObject FindBy(string userName)
   {
      //...Ado .Net command.ExecuteReader, etc.
   }
}

该存储库通过 IoC 容器注入到域服务中,并按如下方式使用:

public class UserDomainService : IUserDomainService
{
   private readonly IRepository Repository;

   public UserDomainService(IRepository repository)
   {
      Repository = repository;
   }

   public User CreateNewUser(User user)
   {
      using(Repository)
      {
         var user = Repository.FindBy(user.UserName);
         if(user != null)
            throw new Exception("User name already exists!");

         Repository.Add(user);
         Repository.Commit();
      }
   }
}

我的想法是,我总是将 Repository 对象放在 using 语句中,因此当它完成时,连接将关闭并被释放,但我认为这是一个问题,因为域服务类仍然存在,并且如果有第二次调用它,它将失败,因为存储库已被销毁。

现在我可以完全控制所有代码,并且我只想设计粗粒度服务调用,但整个事情感觉不太对劲。

我这样做是为了避免域服务知道存储库中的 OpenConnection 和 CloseConnection 方法。

这种设计本质上是不好的还是有更好的方法来做到这一点?

经过深思熟虑:当请求到达时,所有依赖关系树都会在 WCF 级别生成,当然您可以看到连接在那一刻打开,因为它发生在存储库的构造函数中,所以我相信它并没有那么糟糕,因为它是仅在该特定通话期间打开。我的这个假设是正确的还是我在过程中这么早就打开数据库连接做了一些非常糟糕的事情?


注入一个创建您需要的实例的工厂,而不是实例本身。

Take an IRepositoryFactory这样你就可以创建一个IRepository并在每次使用时将其丢弃。这样,域服务或工厂都不需要是一次性的。另外,重要的是,您仍然可以通过注入实现来保持代码抽象,而不是对其进行硬编码。

public class UserDomainService : IUserDomainService
{
   private readonly IRepositoryFactory RepositoryFactory;

   public UserDomainService(IRepositoryFactory factory)
   {
      RepositoryFactory = factory;
   }

   public User CreateNewUser(User user)
   {
      using (IRepository repository = RepositoryFactory.Create())
      {
         var user = repository.FindBy(user.UserName);
         if(user != null)
            throw new Exception("User name already exists!");

         repository.Add(user);
         repository.Commit();
      }
   }
}

您并不总是需要注入您需要的类型。在阅读 Castle Windsor(其思维方式是注册-解析-发布)时,您会发现如果您想在应用程序生命周期中的不确定时间解决问题,建议使用类型工厂。

您知道您需要一个存储库,但不知道when。与其请求存储库,不如请求一些东西creates他们。因此,抽象级别得以维持,并且您没有泄漏任何实现。

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

注入存储库上的 IDisposable 的相关文章

  • Dapper 强类型查询返回默认对象值

    刚刚开始使用 Dapper 并喜欢它 我遇到了问题 它返回正确数量的对象 但它们的属性都有默认值 using var dbConnection Connection await dbConnection OpenAsync const st
  • 在两个 .cpp 文件之间定义全局变量 [重复]

    这个问题在这里已经有答案了 如何在 A cpp 和 B cpp 之间共享 全球化 bool 变量 其中它们都不包含其他 h 文件 他们有其他联合头文件 但彼此没有 我可以在这些共享标头中定义全局变量吗 Thanks 我可以在这些共享标头中定
  • .NET Windows 服务中调用 C# 的 wait 的 I/O 回调是否可以不阻塞?

    我知道在 ASP NET 中 当使用 wait 时工作线程会返回到池中 而 I O 发生在后台 这对于可扩展性非常有用 我的 Windows 服务是一个套接字服务器 它使用 Begin End 样式的异步套接字 I O 混合我的魔法 我知道
  • 浏览器收集哪些值作为回发数据?

    当页面被发送回服务器时 浏览器收集每个控件的当前值并将其粘贴到一个字符串中 然后 该回发数据通过 HTTP POST 发送回服务器 Q1 除了控件的 Text 属性和 SelectedIndexchanged 因此除了用户输入数据 之外 控
  • 禁用除滚动之外的 DataGridView

    我如何配置 datagridview 以便用户只能在行中移动并使用滚动 而没有其他 如果我禁用网格不允许我使用滚动 将您的 datagridview 设置为只读 这将禁用任何编辑 dataGridView1 ReadOnly true 在你
  • TestMethod:异步任务 TestSth() 不适用于 .NET 4.0

    我正在尝试使用 NET 4 0 BCL Async 和 MsTest 运行异步测试方法 看来这个设置不能处理 测试方法 异步Task测试Sth 由于测试用例资源管理器中缺少条目 将签名更改为异步后void 我可以运行测试用例 但结果错误 根
  • C++ 模板参数类型推断

    我有一个这样的C 模板 template
  • 首先EntityFramework数据库 - 类型映射 - 将binary(8)从SQL映射到C#中的int

    在 SQL 内部 我有一个主键为二进制 8 的表 当我使用该表添加到我的模型中时Update Model from Database我可以看到该列有 type Binary 在 C 中 我将该列设为byte 我可以将该列映射到 int 吗
  • IClaimsTransformation 未触发

    我尝试过实施一个IClaimsTransformation我在 ASP NET CORE 3 1 Web 应用程序中找到的类 public class ClaimsTransformer IClaimsTransformation publ
  • AspNetCore.SignalR:无法启动未处于初始状态的连接

    我无法让 ASP NET Core SignalR 应用程序正常运行 我有这个服务器端代码 public class PopcornHub Hub private int Users public async Task BroadcastN
  • 打破条件变量死锁

    我遇到这样的情况 线程 1 正在等待条件变量 A 该变量应该由线程 2 唤醒 现在线程 2 正在等待条件变量 B 该变量应该由线程 1 唤醒 在我使用的场景中条件变量 我无法避免这样的死锁情况 我检测到循环 死锁 并终止死锁参与者的线程之一
  • .NET 的 HttpWebResponse 是否会自动解压缩 GZiped 和 Deflated 响应?

    我正在尝试执行一个接受压缩响应的请求 var request HttpWebRequest HttpWebRequest Create requestUri request Headers Add HttpRequestHeader Acc
  • C# - 命名空间内的类型声明

    在命名空间内而不是在类中声明类型的可能用途是什么 For ex namespace Test public delegate void Ispossible 这是有效的并且不会产生任何编译错误 但我无法想象为什么我们会以这种方式声明它而不是
  • 为什么从绑定返回的对象会忽略额外的参数?

    假设我有一个带有两个参数的函数 void f int x int y 我想绑定其中之一 我可以用std bind如下 auto partiallyBoundF std bind f 10 1 partiallyBoundF仅需要一个参数 但
  • 无效的模板相关成员函数模板推导 - 认为我正在尝试使用 std::set

    我有一个继承自基类模板的类模板 基类模板有一个数据成员和一个成员函数模板 我想从我的超类中调用它 我知道为了消除对成员函数模板的调用的歧义 我必须使用template关键字 我必须明确引用this在超级班里 this gt base mem
  • Visual Studio 2015默认附加库

    当我在 VS 2015 中创建一个空项目时 它会自动将这些库放入 附加依赖项 中 kernel32 lib user32 lib gdi32 lib winspool lib comdlg32 lib advapi32 lib shell3
  • 编译器什么时候内联函数?

    在 C 中 函数仅在显式声明时才内联inline 或在头文件中定义 或者编译器是否允许内联函数 因为他们认为合适 The inline关键字实际上只是告诉链接器 或告诉编译器告诉链接器 同一函数的多个相同定义不是错误 如果您想在标头中定义函
  • 计算两个日期之间的工作日数?

    在C 中 如何计算business 或工作日 两个日期之间的天数 我以前曾经遇到过这样的任务 并且我已经找到了解决方案 当可以避免的时候 我会避免列举其间的所有日子 这里就是这种情况 正如我在上面的一个答案中看到的那样 我什至没有提到创建一
  • 请解释为什么Java和C对此代码给出不同的答案

    public class Test public static void main String args int i 10 i i System out println value of i is i 输出是 10 当我在中执行类似的代码
  • XmlDocument Save 使文件保持打开状态

    我有一个简单的 C 函数 可以创建一个基本的 XML 文件并保存 private void CreateXMlFile string Filename string Name string Company XmlDocument doc n

随机推荐

  • 处理 Datomic 中存储的无序消息?

    背景 在分布式系统中 消息可能会以无序的方式到达 例如 如果消息 A 在时间 T1 发送 消息 B 在时间 T2 发送 则有可能在 A 之前接收到 B 例如 如果 A 是诸如 CustomerRegistered 的消息而 B 是 Cust
  • iOS7 中奇怪的 UITabBar 颜色不一致

    我使用的是 iOS 7tintColor and barTintColor属性来为我的颜色着色UITabBar在 UITabBarController 的子类中使用以下代码 UITabBar appearance setBarTintCol
  • 在 OpenJdk 中,如何使用appendedfontpath属性设置字体目录

    我试图让我的应用程序使用 OpenJdk 安装中特定位置的字体附加字体路径财产 但它对我不起作用 jre1 8 0 121 1 bin java Dappendedfontpath usr lib fonts jar lib songkon
  • 当 URL 中不存在可选参数时找不到 Web API 操作

    请帮忙 我必须更改 Web API 的路由才能使用 URL 中的方法 public class RouteConfig public static void RegisterRoutes RouteCollection routes rou
  • 防止引导工具提示在单击时隐藏

    我想防止工具提示在我单击它时隐藏 除了无论我点击 body 时它都应该隐藏它 即使在选项卡上 工具提示也应该起作用 jsfiddle http jsfiddle net C5GBU 41 http jsfiddle net C5GBU 41
  • Blade.php 方法将结果输出到表单

    我目前正在使用 Laravel 4 2 框架和 twitter bootstrap 设计一个网站 我已经设置了我的master blade php文件 在每个页面的顶部显示一个导航栏 基本上 如果用户登录 我想显示一个导航栏 其选项与用户未
  • 如何将一列中的数据分成两列?

    我最近刚刚开始学习 MS Access 和 SQL Server 中的 SQL 所以我的知识非常有限 但我正在寻找有关 MS Access 中查询的帮助 我知道如何将 2 列合并为 1 列 并用逗号或我想要的任何符号分隔最终结果 但是 我该
  • 错误:找不到您尝试购买的商品

    我是一名安卓初学者 我创建了一个测试应用程序 它只有一个按钮 当您单击它时 它会启动应用内购买 几天前还可以用 但现在不行了 我还检查了其他相关帖子 我尝试了所有 测试帐户 和 活动应用内产品 方法 但它仍然给我相同的错误消息 另外 我尝试
  • 有没有办法更改未使用 basicConfig 配置的记录器对象的文件模式?

    如果我使用 logger logging getLogger Name 创建记录器对象 我无法将文件模式从追加 a 更改为写入 w 如果我将根记录器与 basicConfig 一起使用 则可以 但是当我想要的只是从 DEBUG 级别开始的我
  • 根据匹配的行合并两个csv文件并在linux中添加新列

    我正在使用 java 开发一个应用程序 但为此我需要一个按顺序排列的 csv 文件 我对linux不太了解 但想知道是否有某种方法可以将csv文件合并为所需的格式 我有两个 csv 文件 其中包含数十万条记录 示例如下 name Direc
  • 如何列出Qt5的所有CMake组件?

    我知道在 CMake 中我可以找到并需要我需要的 Qt5 库 代码如下 find package Qt5 5 12 0 REQUIRED COMPONENTS Gui Qml QuickControls2 Svg 但我怎么知道我可以在后面列
  • 在 Fabric8 Kubernetes 客户端 events() API 的 Watcher 中,我可以监视哪些资源?

    我正在探索 无证 events API https github com fabric8io kubernetes client blob master kubernetes client src main java io fabric8
  • Qt 中区分单击事件和双击事件

    我有一个QAbstractItemView需要对单击和双击事件做出反应 根据单击还是双击 操作会有所不同 发生的问题是在双击事件之前接收到单击事件 是否有推荐的方法 最佳实践来区分两者 当用户实际双击时 我不想执行单击操作 我正在使用 Qt
  • 在内联表单集中使用 Django FileField

    在我的应用程序中上传文件时遇到问题 用户提交报告并可以添加附件 通过外键关系 我已经显示了内联表单 如果我将其留空 它就会工作 但是当我尝试上传文件然后提交表单时 我收到 500 错误 基本报告已制作 但内联的附件未保存 forms py
  • 如何调用Fragment的onResume()

    我使用了导航抽屉 其中有许多片段 我想调用fragment的onResume 我需要从服务器加载更新的数据 onResume 当你的Activity onResume 已被调用 您不必调用onResume in a Fragment 阅读本
  • Python 编码风格 - 多个返回语句[关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 对于同一任务 我编写了两个不同的函数 我想知道哪一个使用起来更优雅 任务是检查一个pydot如果它看到请求的节点 则返回对象 如果是 则返回该节
  • 让 google Recaptcha 能够处理域名中的特殊字符

    我正在为域名中包含瑞典字符 的网站设置 API 密钥 http s lja io http s C3 A4lja io 但它没有初始化验证码 然后尝试使用等效 url 的 api 密钥http xn slja loa io http xn
  • android studio 模拟器无法初始化 DirectSoundCapture

    我在 android studio 3 2 中只有一个基本的 helloworld 应用程序 我正在尝试运行一些模拟器来使用 AVD 管理器测试该应用程序 但模拟器只是停留在 google 徽标中 最终 android studio 超时并
  • Android Studio 2 Beta 5 中的构建变体中测试工件选择器丢失/消失

    为了在 Android Studio 中运行 Instrumentation Tests 我通常通过 Build Variants 窗 口选择 Android Instrumentation Tests 作为要构建的测试工件 我最近升级到
  • 注入存储库上的 IDisposable

    我有以下 ADO Net 存储库 public class Repository IRepository IDisposable private readonly IUnitOfWork UnitOfWork private SqlConn