Soh*_*aza 6 c# design-patterns
我有一个方法,它按顺序在内部执行不同的子操作,并且在我想要回滚整个操作的任何子操作失败时.
我的问题是子操作不是所有的数据库操作.这些主要是系统级更改,例如在Windows注册表中添加内容,在指定路径创建文件夹以及设置权限等.子操作可能不止于此.
想要做这样的事情;
CreateUser(){
CreateUserFtpAccount();
CreateUserFolder();
SetUserPermission();
CreateVirtualDirectoryForUser();
....
....
....
and many more
}
Run Code Online (Sandbox Code Playgroud)
如果上次操作失败,我想回滚所有以前的操作.
那么,这样做的标准方法是什么?是否有设计模式可以处理这个?
注意:我正在使用 C#.net
这是一种方法:
使用命令模式,您可以创建可撤消的操作。对于每个操作,您都注册相关命令,以便在发生失败情况时可以撤消已执行的命令。
例如,这可能全部属于实现IDisposable并放入using块中的类似事务的上下文对象。可撤消的操作将注册到此上下文对象。在处置时,如果未提交,将对所有注册的命令执行“撤消”。希望能帮助到你。缺点是您可能必须将某些方法转换为类。但这可能是一种必要的罪恶。
代码示例:
using(var txn = new MyTransaction()) {
txn.RegisterCommand(new CreateUserFtpAccountCommand());
txn.RegisterCommand(new CreateUserFolderCommand());
txn.RegisterCommand(new SetUserPermissionCommand());
txn.RegisterCommand(new CreateVirtualDirectoryForUserCommand());
txn.Commit();
}
class MyTransaction : IDisposable {
public void RegisterCommand(Command command){ /**/ }
public void Commit(){ /* Runs all registered commands */ }
public void Dispose(){ /* Executes undo for all registered commands */ }
}
class UndoableCommand {
public Command(Action action) { /**/ }
public void Execute() { /**/ }
public void Undo{ /**/ }
}
Run Code Online (Sandbox Code Playgroud)
更新:
您提到您有数百个此类可逆操作。UndoableCommand在这种情况下,您可以采取更实用的方法并彻底摆脱它。您可以注册代表,如下所示:
using(var txn = new MyTransaction()) {
txn.Register(() => ftpManager.CreateUserAccount(user),
() => ftpManager.DeleteUserAccount(user));
txn.Register(() => ftpManager.CreateUserFolder(user, folder),
() => ftpManager.DeleteUserFolder(user, folder));
/* ... */
txn.Commit();
}
class MyTransaction : IDisposable {
public void Register(Action operation, Action undoOperation){ /**/ }
public void Commit(){ /* Runs all registered operations */ }
public void Dispose(){ /* Executes undo for all registered and attempted operations */ }
}
Run Code Online (Sandbox Code Playgroud)
请注意,您需要小心使用这种方法的闭包。
| 归档时间: |
|
| 查看次数: |
168 次 |
| 最近记录: |