Using pattern
|
Je tomu již dlouhá doba, co jsem psal spotík o užívání bloku using
v jazyce C# pro třídy implementující rozhranní System.IDisposable
. Tohoto bloku se dá využít k logickému členění kódu do bloků a vytvořit tak syntax sugar na úrovni API.
Ukázky užití
S using patternem se v moderních API dá potkat celkem často. První ukázka je z mockovacího frameworku Rhino Mocks. Používá se pro nahrávání a přehrávání chování mockovaného objektu.
MockRepository mocks = new MockRepository();
IDependency dependency = mocks.CreateMock<IDependency>();
using(mocks.Record()) {
Expect.Call(dependency.GetSomething("parameter")).Return("result");
dependency.DoSomething();
}
using(mocks.Playback()) {
Subject subject = new Subject(dependency);
subject.DoWork();
}
Using pattern usnadňuje čtení takovéhoto kódu a hned je jasná i logická struktura.
Další ukázka pochází z ASP.NET MVC frameworku, kde se using pattern používá v HTML helperu pro generování formuláře.
<% using(Html.Form<HomeController>(action => action.Index())) { %>
...
<% } %>
Implementace
Základem, tedy, je blok using
, který slouží k bezpečnému zavolání metody Dispose
objektu implementujícího rozhranní System.IDisposable
. Jak na to, když v using bloku předáváme metodu a ne objekt? Jednoduše, musíme vrátit v metodě objekt, který se o špinavou práci postará. V podstatě ani nemusí být nijak inteligentní.
public class UsingPattern : IDisposable {
private WorkerMethod _method;
public delegate void WorkerMethod();
public UsingPattern(WorkerMethod method) {
_method = method;
}
public void Dispose() {
_method();
}
}
Užití v našem API je pak celkem triviální.
public class SomeClass {
public UsingPattern SomeMethod() {
Console.WriteLine("Zacatek bloku");
return new UsingPattern(() => Console.WriteLine("Konec bloku"));
}
}
public class OtherClass {
public void Consumer() {
var some = new SomeClass();
using (some.SomeMethod()) {
Console.WriteLine("Blok");
}
}
}