我不确定这是否可行,我可能需要为每个实现编写扩展方法。以下是一些示例代码:
public interface IBaseService<T>
{
IUnitOfwork UnitOfWork {get;}
}
public interface IService<T>: IBaseService<T>
{
IEnumerable<T> GetAll();
T GetById(Guid id);
}
public interface IUserService: IService<User>
{
User FindByUsernameAndPassword(string username, string password)
}
public class BaseService<T>: IService<T>
{
public BaseService(IRepository<T> repository)
{
_repository = repository
}
public virtual IEnumerable<T> GetAll(){....};
public virtual T GetById(Guid id){....};
IUnitOfWork UnitOfWork {get {return _repository.UnitOfWork;}}
}
public class UserService: BaseService<User>, IUserService
{
...
}
public static class ServiceExtensions
{
public static IBaseService<T> EnableLazyLoading<T>(this IBaseService<T> service, bool lazyLoad = True)
{
service.UnitOfWork.EnableLazyLoad(lazyLoad);
return service;
}
}
所以,假设我使用的是UserService。当我在UserService上调用扩展方法时,是否可以让它返回正确的IBaseService实现,还是需要为每个实现创建和扩展方法?:
示例:
userService.EnableLazyLoading(false).FindByUsernameAndPassword("ddivita","123456")
答案 0 :(得分:3)
你可以这样做:
public static S EnableLazyLoading<T, S>(this S service, bool lazyLoad = true)
where S : IBaseService<T>
{
service.UnitOfWork.EnableLazyLoad(lazyLoad);
return service;
}
答案 1 :(得分:2)
好的,这可能适用于您的设计,也可能不适用,但它建立在Felix的答案(他应该得到赞誉)的基础上,并使其可推断。
由于您的UnitOfWork
类不依赖于类型T
,因此您可以创建一个非{0}包含IBaseService
成员的UnitOfWork
,然后生成{{1}像这样扩展IBaseService<T>
:
IBaseService
然后,保持其他类设计正常,并将扩展方法写为:
public interface IBaseService
{
// all non-type-T related stuff
IUnitOfwork UnitOfWork {get;}
}
public interface IBaseService<T> : IBaseService
{
// .. all type T releated stuff
}
由于我们现在不需要public static S EnableLazyLoading<S>(this S service, bool lazyLoad = true)
where S : IBaseService
{
service.UnitOfWork.EnableLazyLoad(lazyLoad);
return service;
}
来获取IBaseService<T>
,因此我们无需指定导致推理有问题的第二个类型参数UnitOfWork
。现在我们可以完全按照您的意愿编写代码,因为它现在可以推断T
是S
而无需了解类型UserService
(T
):
User
当然,正如我所说,这假设userService.EnableLazyLoading(false).FindByUsernameAndPassword("ddivita","123456");
不需要UnitOfWork
类型的任何内容。
正如我所说的那样,@ Felix应该得到答案,但只是想扩展一下如何能够推断它能够避免传递泛型类型参数。不过,赞成票: - )