2010-07-30 4 views
3

추상 클래스의 사용과 결합 된 저장소 패턴의 문제가 발생합니다.저장소 패턴 및 추상 클래스의 문제점

나는 추상 형식의 ICollection을 반환하는 단일 메서드를 구현하는 저장소가 있습니다.

public class Country : Location 
{ 
    public override string Name { get; set; } 
    public override LocationType Type { get { return LocationType.Country; } } 
} 

여기 내 저장소입니다 :

public class LocationsRepository : Locations.Repository.ILocationsRepository 
{ 
    public ICollection<Location> GetAllLocations() 
    { 
     Country america = new Country { Name = "United States" }; 
     Country australia = new Country { Name = "Australia" }; 
     State california = new State { Name = "California", Country = america }; 

     return new List<Location>() { america, australia, california }; 
    } 
} 

여기
public abstract class Location 
{ 
    public abstract string Name { get; set; } 
    public abstract LocationType Type { get; } 
} 

그 추상 클래스의 콘크리트 구현의 :

은 여기 내 추상적 인 클래스의

지금까지 모두 좋았습니다.

지금 서비스 :

public class CountryService : ICountryService 
{ 
    private ILocationsRepository repository; 

    public CountryService() 
    { 
     // in reality this is done by DI, but made 'greedy' for simplicity. 
     this.repository = new LocationsRepository(); 
    } 

    public List<Country> GetAllCountries() 
    { 
     // errors thrown by compiler 
     return repository.GetAllLocations() 
         .Where(l => l.Type == LocationType.Country) 
         .ToList<Country>(); 
    } 
} 

문제가있다. 나는 추상적 인 유형의 ICollection<T>을 반환하는 저장소에서 구체적인 유형의 목록 (Country)을 반환하려고합니다.

2 컴파일 타임 오류를 가져 오기 :

'System.Collections.Generic.IEnumerable' 'ToList'최고의 확장 메서드 오버로드 '을 System.Linq에 대한 정의가 포함되어 있지 않습니다. ParallelEnumerable.ToList (System.Linq.ParallelQuery)는 '일부 잘못된 인수가

인스턴스 인수 : 에서 'System.Collections.Generic.IEnumerable' 'System.Linq.ParallelQuery'

그래서

, 내가 어떻게 구현할 수 이 패턴을 변환 할 수 없습니다?

나는 추상적 인 형식을 인스턴스화 할 수 없다는 점을 이해할 수 있으므로 열거 자 (.ToList)가 인스턴스화하려고 시도하므로 오류가 발생합니까? 당신이하려고 어떤 메신저 이해하지 못하는 경우

:

  • 내가 원하는 내 저장소를
  • 가 내 서비스를 원하는 추상적 인 유형의 ICollection<T>을 반환 (내가 각 콘크리트를해야합니다 형식)을 반환하는 단일 저장소 메서드를 기반으로 구체적인 형식 목록

LINQ 구문의 경우입니까? 아니면 내 디자인 패턴이 완전히 틀렸어?난 당신이 목록을 생성 할 수있는에 일반 ToList<T> 방법을 착각 한 생각

return repository.GetAllLocations() 
    .Where(l => l.Type == LocationType.Country) 
    .Select(l => l as Country).ToList(); 

:

는 문제에 대한 해결책은 아주 간단합니다

답변

7
repository.GetAllLocations().OfType<Country>().ToList(); 

가 그리고 당신은 심지어 내가 이고르가 올바른지 믿는 LocationType 열거

+1

+1 그게 최선의 해결책입니다. –

+1

굉장했기 때문에 LINQ 문제 였고 추상적/저장소 문제는 아닙니다. 감사!! – RPM1984

2

, 당신은 당신의 LINQ 표현에 새로운 나라를 만들어야합니다 새로운 유형 T은 항상 소스 모음에서 유추됩니다. 일반적으로 한 유형의 콜렉션을 다른 유형의 콜렉션으로 변환하려면 Select을 사용하십시오.

+0

필요하지 않습니다 - SELECT 절에 새로운 요소로 캐스팅. 나는 내 도메인 엔티티에 Linq-to-Sql 엔티티를 매핑하는 내 리포지토리에서이 모든 작업을 수행하며이 인라인 Select()는 정확 해 보입니다. +1 또한 내부 속성 설정자/가져 오기를 사용하여 논리를 사용하여 추가 구성원을 공개적으로 액세스 할 수있게 만드는 도메인 엔터티에 내부를 설정할 수 있습니다. – eduncan911

+0

이것도 작동합니다 - 그러나 메신저는 @Necros 응답에 기대고 있기 때문에 ... 음 ... 적은 코드가 더 낫습니다 (그리고 열거 형에 의존하지 않습니다) 이 답변과 @Necros 답변의 차이점은 누구나 상상할 수 있습니까? – RPM1984