返回接口的正确实现的扩展方法

本文关键字:扩展 方法 实现 接口 返回 | 更新日期: 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,这使得推理有问题。所以现在我们可以完全按照你想要的方式编写代码,因为它现在可以推断出SUserService,而不需要知道T (User)的类型:

userService.EnableLazyLoading(false).FindByUsernameAndPassword("ddivita","123456");

当然,正如我所说的,这是假设UnitOfWork不需要T类型的任何内容。

正如我所说,@Felix应该得到答案,但只是想扩展如何使其可推断以避免必须传递泛型类型参数。虽然向上投票是值得赞赏的:-)