处置来自同一对象的对象

Mat*_*ero 9 c# dispose fluent

我正在设计一个流畅的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)

代码似乎编译得很好,但我正在寻找可能因此而出现的奇怪行为或错误.这是不好的做法吗?

Dov*_*opa 5

你可以有这样的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完成.