Используйте анонимный метод для упаковки вызова.
Например, если у вас есть класс слоя данных, добавьте аналогичный метод к слою данных:
public delegate void DoSomethingInvoker();
class DataLayer
{
//myReader needs to be declared externally in other to access it from the doSomething delegate
public void MethodThatGetsAsXmlReader(XmlReader myReader, DoSomethingInvoker doSomething)
{
myReader = GetXmlReaderFromDB();
doSomething();
CloseDbConnection(); //close connections, do cleanup, and any other book keeping can be done after the doSomething() call
}
}
Чтобы позвонить / использовать его, вы просто делаете это в своем классе высокого уровня
DataLayer dl = new DataLayer();
XmlReader myReader = null; //variables declared outside the scope of the anonymous method are still accessible inside it through the magic of closures
dl.MethodThatGetsAsXmlReader(myReader, delegate()
{
//do all work that involves myReader here
myReader.read();
Console.out.println(myReader.value);
});
//at this point myReader is closed and cannot be used
Обычно вы передаете код, который вы хотите выполнить, в слой данных, слой данных извлекает xmlreader, вызывает ваш код против него, а затем выполняет очистку.
Я использую похожую технику для переноса логики транзакций в своем коде
DataLayer dl = new DataLayer();
dl.Transaction(delegate()
{
dl.DbCall1();
dl.DbCall2();
dl.DbCall3();
});
Это делает код красивым и читаемым, в то же время сохраняя его организованным и многоуровневым;