Извините, если уже был дан ответ, но я думаю, что на самом деле мне не хватает формального образования, чтобы правильно задавать этот вопрос, и, следовательно, также не хватает правильных критериев для поиска это успешно.Как сделать ссылку на имя метода на строго типизированном интерфейсе
У меня есть API, который имеет несколько вызовов, которые выполняют почти то же самое, но действуют на разные объекты ввода с использованием другого метода, но всегда образуют один и тот же интерфейс. Я хочу, чтобы вырезать фрагмент & из процессов вызова метода API, чтобы общий код делался одинаковым во всех вызовах метода. Мне удалось получить рабочее решение с использованием дженериков для входных и выходных объектов, и я делаю ссылку на имя метода, которое вызывается из строки. Я хотел бы, чтобы ссылки на методы были строго типизированы, а не на основе строк, так что переименование имени метода при повторном факторинге потенциально не оставило бы «магическую» строку имени метода, ожидающего взорваться во время выполнения.
Ниже представлена очень упрощенная версия того, чего я пытаюсь достичь.
class ARequest { };
class AResponse { };
class BRequest { };
class BResponse { };
interface IWorker
{
AResponse DoA(ARequest aRequest);
BResponse DoB(BRequest bRequest);
}
class Worker : IWorker
{
public AResponse DoA(ARequest aRequest)
{
return new AResponse();
}
public BResponse DoB(BRequest bRequest)
{
return new BResponse();
}
}
class Program
{
static void Main(string[] args)
{
// current concrete copy & paste implementation
var a1 = API.DoA(new ARequest { });
var b1 = API.DoB(new BRequest { });
// new generic implementation
var a2 = API.DoA2(new ARequest { });
var b2 = API.DoB2(new BRequest { });
}
}
static class API
{
// current concrete copy & paste implementation
public static AResponse DoA(ARequest aRequest)
{
// lots of common code for logging & preperation
var worker = GetWorker();
return worker.DoA(aRequest);
}
public static BResponse DoB(BRequest bRequest)
{
// lots of common code for logging & preperation
var worker = GetWorker();
return worker.DoB(bRequest);
}
private static IWorker GetWorker()
{
return new Worker();
}
// new generic implementation Attempt
public static AResponse DoA2(ARequest aRequest)
{
return DoGen<ARequest, AResponse>(aRequest, "DoA"); // how to make references to DoA and DoB methods on the IWorker strongly typed?
}
public static BResponse DoB2(BRequest bRequest)
{
return DoGen<BRequest, BResponse>(bRequest, "DoB"); // how to make references to DoA and DoB methods on the IWorker strongly typed?
}
public static TResponse DoGen<TRequest, TResponse>(TRequest requestObj, string methodname)
where TRequest : class
where TResponse : class
{
// lots of common code for logging & preperation
var worker = GetWorker();
var mi = worker.GetType().GetMethod(methodname);
var result = mi.Invoke(worker, new Object[] { requestObj });
return result as TResponse;
}
}
ли типы реагирования, связанные каким-либо образом? – Foo42
Взгляните на это сообщение в блоге, он описывает модель, которая делает то, что вам нужно: http://www.cuttingedge.it/blogs/steven/pivot/entry.php?id=92 – Steven
Foo42: У них есть общие поля в конечной реализации, которые относятся к общему базовому классу. В этом примере они не связаны. –