2011-10-27 6 views
4

이것이 가능한지 잘 모르겠습니다. 각 구현에 확장 메서드를 작성해야 할 수도 있습니다. 다음은 몇 가지 예제 코드입니다.올바른 인터페이스 구현을 반환하는 확장 메서드?

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.EnableLazyLoading(false).FindByUsernameAndPassword("ddivita","123456") 
+0

그래서 분명히하기 위해 그것이 무엇이든간에 새로운 버전을 만들길 원하십니까? –

+0

올바른 구현을 반환하는 IBaseServcie 의 모든 구현에서 사용할 하나의 확장 메서드 만 작성하고 싶습니다. 내 예제에서는 EnableLazyLoading 확장을 호출 할 때 IUserService를 반환하는 방법을 찾아야합니다. – DDiVita

+0

오! 알 수 있듯이, 호출 된 특정 유형을 반환하고 새 인스턴스를 생성하지 않기를 원합니다. –

답변

3

당신에게 : 나는 UserService의 확장 메서드를 호출 할 때, 그것은 IBaseService의 적절한 구현을 반환하거나 내가 각 구현?

예를 들어 작성하고 확장 메서드해야하나요 가질 수 있습니다 이런 식 수행 할 수 있습니다

public static S EnableLazyLoading<T, S>(this S service, bool lazyLoad = true) 
    where S : IBaseService<T> 
{ 
    service.UnitOfWork.EnableLazyLoad(lazyLoad); 
    return service; 
} 
+0

나는 같은 대답을 내놓았다. 문제는 타입을 추측 할 수 없다는 것이다. (OP가 좋든 그렇지 않든간에) 명시 적으로 다음과 같이 호출해야한다 :'userService.EnableLazyLoading (false) ... ' –

+0

예, 맞습니다. 그러나이 방법으로 확장 메서드를 n 번 만들면 더 좋습니다. 확장 메서드가 여러 개있는 경우 할 수있는 유일한 방법은 인터페이스에서 추상 클래스로 변경하는 것입니다. –

+0

오, 전적으로 동의합니다. 다만 아래쪽을 지적하십시오. –

2

좋아을,이 또는 디자인 작동하지 않을 수 있지만 펠릭스의 대답을 기반으로 (그는에 대한 신용을 얻을해야하는)하고 추론-수 있습니다. 그런 다음

public interface IBaseService 
{ 
    // all non-type-T related stuff 
    IUnitOfwork UnitOfWork {get;} 
} 

public interface IBaseService<T> : IBaseService 
{ 
    // .. all type T releated stuff 
} 

을의 나머지 부분을 계속 :

당신의 UnitOfWork 클래스 유형 T에 의존하지 않기 때문에, 당신은 UnitOfWork 구성원을 포함하는 비 제네릭 인 IBaseService를 만들 수 있습니다, 다음 IBaseService<T> 지금처럼 IBaseService을 확장 할 수 있도록

public static S EnableLazyLoading<S>(this S service, bool lazyLoad = true) 
    where S : IBaseService 
{ 
    service.UnitOfWork.EnableLazyLoad(lazyLoad); 
    return service; 
} 

이 때문에 우리가 GE에 IBaseService<T> 필요하지 않습니다 :로 정상적으로 수업 설계 및 확장 방법을 쓰기 t UnitOfWork 이제는 추론에 문제가되는 두 번째 유형 매개 변수 T을 지정할 필요가 없습니다. 내가 말했듯이, 물론

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

, 이것은 가정된다 : 그래서 지금 우리는 지금 유형 T (User)에 대해 알아야 할 필요없이 SUserService입니다 추론 할 수 있기 때문에 당신이 원하는대로 정확하게 코드를 작성할 수 있습니다 UnitOfWork에는 T 유형의 항목이 필요하지 않습니다.

내가 말했듯이 @Felix는 대답 할 가치가 있지만 그것을 추론 할 수있는 방법을 확장하려고했습니다. 제네릭 형식 매개 변수를 전달하지 않아도됩니다. Up-vote는 높이 평가됩니다. :-)

+0

오, 정말 훌륭합니다! – DDiVita

+0

@DDiVita : 고마워. 필릭스가 대답 할 자격이 있다고 말했듯이, 나는 그의 일을 계속하고 있었다. –

+1

위대한 작품, btw. My UoW는 입력되지 않았으므로 완벽한 솔루션이었습니다. 너와 펠릭스 덕분에. – DDiVita

관련 문제