- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
在 Web 应用程序中,一个工作单元负责事务管理。
但是 Windows 应用程序呢?
据我所知,存储库是我的数据访问层和业务层之间的连接器。它从我的业务层隐藏了所有数据访问内容。
使用这个事实让我想到将所有事务内容放入存储库中。
但我读到在存储库上使用 Commit/RollBack 方法违反了存储库的意图。
我问自己谁负责非 Web 应用程序中的事务管理,以及如何从业务层隐藏事务/Nhibernate 内容?
最佳答案
一般的回答是“谁实例化 ISession
就应该处理掉它。如果事务还没有提交,这实际上是回滚。”
我已经成功地使用命令模式来定义我想对工作单元执行的操作。假设我们有一个 Person
实体,我们可以做的事情之一就是更改一个人的名字。让我们从实体开始:
public class Person
{
public virtual int Id { get; private set; }
public virtual string Name { get; private set; }
public virtual void ChangeName(string newName)
{
if (string.IsNullOrWhiteSpace(newName))
{
throw new DomainException("Name cannot be empty");
}
if (newName.Length > 20)
{
throw new DomainException("Name cannot exceed 20 characters");
}
this.Name = newName;
}
}
像这样定义一个简单的 POCO 命令:
public class ChangeNameCommand : IDomainCommand
{
public ChangeNameCommand(int personId, string newName)
{
this.PersonId = personId;
this.NewName = newName;
}
public int PersonId { get; set; }
public string NewName { get; set; }
}
...和命令的处理程序:
public class ChangeNameCommandHandler : IHandle<ChangeNameCommand>
{
ISession session;
public ChangeNameCommandHandler(ISession session)
{
// You could demand an IPersonRepository instead of using the session directly.
this.session = session;
}
public void Handle(ChangeNameCommand command)
{
var person = session.Load<Person>(command.PersonId);
person.ChangeName(command.NewName);
}
}
目标是存在于 Session/Work 范围之外的代码可以做这样的事情:
public class SomeClass
{
ICommandInvoker invoker;
public SomeClass(ICommandInvoker invoker)
{
this.invoker = invoker;
}
public void DoSomething()
{
var command = new ChangeNameCommand(1, "asdf");
invoker.Invoke(command);
}
}
命令的调用意味着“在一个工作单元上执行此命令”。这是我们希望在调用命令时发生的情况:
IHandle<ChangeNameCommand>
来自 IoC 范围所以这是一个使用 Autofac 的例子作为 IoC 容器:
public class UnitOfWorkInvoker : ICommandInvoker
{
Autofac.ILifetimeScope scope;
public UnitOfWorkInvoker(Autofac.ILifetimeScope scope)
{
this.scope = scope;
}
public void Invoke<TCommand>(TCommand command) where TCommand : IDomainCommand
{
using (var workScope = scope.BeginLifetimeScope("UnitOfWork")) // step 1
{
var handler = workScope.Resolve<IHandle<TCommand>>(); // step 3 (implies step 2)
handler.Handle(command); // step 4
var session = workScope.Resolve<NHibernate.ISession>();
session.Transaction.Commit(); // step 5
} // step 6 - When the "workScope" is disposed, Autofac will dispose the ISession.
// If an exception was thrown before the commit, the transaction is rolled back.
}
}
注意:UnitOfWorkInvoker
我在这里展示的违反了SRP - 这是一个 UnitOfWorkFactory
, 一个 UnitOfWork
, 和一个 Invoker
一体。在我的实际实现中,我将它们分解。
关于c# - Nhibernate:谁负责非 web 应用程序中的事务管理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6835795/
我新发现了 Perl fork ,我非常喜欢。但有一件事让我担心——如果我只是左右分离进程,这肯定会在某个地方引起一些问题。是否应该使用一种合理的检查来确保我的小应用程序不会占用我机器的所有资源? 拿
谁负责 MVVM 中的异步数据获取?例如,我的 View 有 5 个不同的数据集合要获取,我希望按预定义的顺序异步检索这些数据。为此,我使用协程和任务。 问题:VM 是否对此负责,我的模型/存储库应该
我有什么 ember-cli POD 结构。我有嵌套的路由,因此有以下文件夹结构: | |_pods |_items |_index | |_
我有一个 C# WPF 应用程序,它从数据库中读取数据然后做一些工作。但问题是当我读取数据时,我的 UI 没有响应。我已经尝试过任务和调度程序。他们都没有帮助。下面的代码在 button_click
在使用 /sys/class/leds/ 摆弄 LED 之后,我现在正试图了解如何使用 linux kernel power supply attributes 控制计算机中的电池。 ,特别是 CHA
我在我的桌面应用程序中做了一些非常简单的错误记录,该应用程序通过 SerialPort 与设备通信。我做的一件事是设置一个全局异常捕获器,它除了使用以下方法记录堆栈跟踪外什么都不做: AppDomai
我是一名优秀的程序员,十分优秀!