我正在设计一个流畅的API,其用法有点像这样:
IUser user = work
.Timeout(TimeSpan.FromSeconds(5))
.WithRepository(c => c.Users)
.Do(r => r.LoadByUsername("matt"))
.Execute();
Run Code Online (Sandbox Code Playgroud)
所以,让我们说work是类型IUnitOfWork,但该方法WithRepository(c => c.Users)返回称为界面IActionFlow<IUserRepository>是IDisposable.
当我调用Execute()并获得最终结果时,我失去了对该IActionFlow<IUserRepository>实例的引用,因此我无法处理它.
将实例自身放在Execute()方法上有什么缺点?
就像是:
public TResult Execute()
{
// ...
Dispose();
return result;
}
Run Code Online (Sandbox Code Playgroud)
代码似乎编译得很好,但我正在寻找可能因此而出现的奇怪行为或错误.这是不好的做法吗?
你可以有这样的Using方法:
public static TResult Using<TDisposable, TResult>(Func<TDisposable> factory,
Func<TDisposable, TResult> fn) where TDisposable : IDisposable {
using (var disposable = factory()) {
return fn(disposable);
}
}
Run Code Online (Sandbox Code Playgroud)
然后你的代码看起来像这样:
var user = Using(() => work.
Timeout(TimeSpan.FromSeconds(5)).
WithRepository(c => c.Users),
repository => repository.Do(r => r.LoadByUsername("matt")).
Execute());
Run Code Online (Sandbox Code Playgroud)
这将使你的API保持流畅,并在同一时间,你将部署WithRepository在同一时刻Execute完成.