Powiedzmy mam interfejs usługi, który wygląda tak:Dlaczego w niniejszym kodzie nie działa inferencja typów?
public interface IFooService
{
FooResponse Foo(FooRequest request);
}
chciałbym spełnić pewne obawy przekrojowe podczas wywoływania metody na usługi takie jak; na przykład chcę ujednolicić rejestrowanie żądań, rejestrowanie wydajności i obsługę błędów. Moje podejście jest mieć wspólną bazę „klasy repozytorium” z metody Invoke
że dba o wywołanie metody i robi inne rzeczy wokół niego moja klasa podstawowa wygląda mniej więcej tak:..
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);
}
}
Działa to dobrze, jednak całe moje celem dokonywania czystsze kod jest udaremnione przez fakt, że typ wnioskowanie nie działa zgodnie z oczekiwaniami na przykład, jeśli mam napisać metodę tak:.
public class FooRepository : BaseRepository<IFooService>
{
// ...
public BarResponse CallFoo(...)
{
FooRequest request = ...;
var response = this.Invoke(svc => svc.Foo, request);
return response;
}
}
otrzymuję ten błąd kompilacji:
The type arguments for method ... cannot be inferred from the usage. Try specifying the type arguments explicitly.
Oczywiście, mogę go naprawić, zmieniając moje wezwanie do:
var response = this.Invoke<FooRequest, FooResponse>(svc => svc.Foo, request);
Ale chciałbym, aby tego uniknąć. Czy istnieje sposób na przerobienie kodu, aby móc skorzystać z wnioskowania o typie?
Edit:
Należy również wspomnieć, że wcześniejsze podejście było użyć metodę rozszerzenia; typ wnioskowanie o to działało:
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);
}
}
Widzę; to ma sens. – Jacob