假设我有一个如下所示的服务接口:
public interface IFooService
{
FooResponse Foo(FooRequest request);
}
在调用此类服务的方法时,我想解决一些横切关注点;例如,我想要统一的请求日志记录、性能日志记录和错误处理。我的方法是拥有一个通用的基础“存储库”类,其中包含一个Invoke
方法,该方法负责调用该方法并围绕它做其他事情。我的基类看起来像这样:
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);
}
}
这工作正常。但是,类型推断未按预期工作这一事实阻碍了我使代码更清晰的整个目标。例如,如果我编写这样的方法:
public class FooRepository : BaseRepository<IFooService>
{
// ...
public BarResponse CallFoo(...)
{
FooRequest request = ...;
var response = this.Invoke(svc => svc.Foo, request);
return response;
}
}
我得到这个编译错误:
方法 ... 的类型参数无法从用法中推断出来。尝试明确指定类型参数。
显然,我可以通过将调用更改为:
var response = this.Invoke<FooRequest, FooResponse>(svc => svc.Foo, request);
但我想避免这种情况。有没有办法重新编写代码以便我可以利用类型推断?
编辑:
我还应该提到,早期的方法是使用扩展方法;对此有效的类型推断:
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);
}
}