Digamos que tengo una interfaz de servicio que tiene este aspecto:¿Por qué la inferencia de tipo no funciona en este código?
public interface IFooService
{
FooResponse Foo(FooRequest request);
}
me gustaría que cumplir con algunos conceptos transversales al llamar a métodos en los servicios de este tipo; por ejemplo, quiero el registro unificado de solicitudes, el registro de rendimiento y el manejo de errores. Mi enfoque es tener una base común "clase repositorio' con un método Invoke
que se encarga de invocar el método y hacer otras cosas que mi clase base es como la siguiente:..
public class RepositoryBase<TService>
{
private Func<TService> serviceFactory;
public RepositoryBase(Func<TService> serviceFactory)
{
this.serviceFactory = serviceFactory;
}
public TResponse Invoke<TRequest, TResponse>(
Func<TService, Func<TRequest, TResponse>> methodExpr,
TRequest request)
{
// Do cross-cutting code
var service = this.serviceFactory();
var method = methodExpr(service);
return method(request);
}
}
Esto funciona bien sin embargo , toda mi objetivo de hacer el código más limpio es frustrado por el hecho de que la inferencia de tipos no está funcionando como se espera, por ejemplo, si escribo un método como este:.
public class FooRepository : BaseRepository<IFooService>
{
// ...
public BarResponse CallFoo(...)
{
FooRequest request = ...;
var response = this.Invoke(svc => svc.Foo, request);
return response;
}
}
consigo este error de compilación:
The type arguments for method ... cannot be inferred from the usage. Try specifying the type arguments explicitly.
Obviamente, puedo solucionarlo cambiando mi llamada a:
var response = this.Invoke<FooRequest, FooResponse>(svc => svc.Foo, request);
Pero me gustaría evitar esto. ¿Hay alguna manera de volver a trabajar el código para que pueda aprovechar la inferencia de tipo?
Editar:
También debería mencionar que un enfoque anterior fue utilizar un método de extensión; inferencia de tipos para este funcionó:
public static class ServiceExtensions
{
public static TResponse Invoke<TRequest, TResponse>(
this IService service,
Func<TRequest, TResponse> method,
TRequest request)
{
// Do other stuff
return method(request);
}
}
public class Foo
{
public void SomeMethod()
{
IService svc = ...;
FooRequest request = ...;
svc.Invoke(svc.Foo, request);
}
}
Veo; eso tiene sentido. – Jacob