返回接口的正确实现的扩展方法
本文关键字:扩展 方法 实现 接口 返回 | 更新日期: 2023-09-27 18:12:38
我不确定这是否可能,我可能需要为每个实现编写扩展方法。下面是一些示例代码:
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")
你可以这样做:
public static S EnableLazyLoading<T, S>(this S service, bool lazyLoad = true)
where S : IBaseService<T>
{
service.UnitOfWork.EnableLazyLoad(lazyLoad);
return service;
}
好吧,这可能适用于你的设计,也可能不适用,但它建立在Felix的答案(他应该得到赞扬)之上,并使其可推断。
因为你的UnitOfWork
类不依赖于T
类型,你可以创建一个包含UnitOfWork
成员的非泛型IBaseService
,然后让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
不需要T
类型的任何内容。
正如我所说,@Felix应该得到答案,但只是想扩展如何使其可推断以避免必须传递泛型类型参数。虽然向上投票是值得赞赏的:-)