5

내가 제공 IRep <A>와 IRep <B> 구현 둘 다 두 POCO 유형, <B A와 B 나는 각각의 저장소가, 의원 <A> 및 담당자를>,이 IoC 컨테이너 (이 경우 AutoFac)에 의해 설정됩니다.AutoFac IOC의, DDD, 간 저장소 종속성

DB (또는 무엇이든)의로드 온 디맨드, 지연된 메모리 내장 콜렉션, 캐시 된 웹 서비스 결과 등 여러 종류의 리포지토리가 있습니다. 호출자는 차이점을 알 수 없습니다. Rep <A> 및 Rep <B>은 A와 B가별로 변하지 않고 오랜 시간 동안 살기 때문에 인 메모리 컬렉션이됩니다.

B의 속성 중 하나는 A입니다. 이제 B가 A를 요청하면 B는 IRep <A>을 찾아 A를 반환합니다. 매번이 작업을 수행합니다. B의 A에 대한 모든 요청에는 IRep <A> .Find()가 포함됩니다. 윗부분은 B가 A의 것을 잡아 내지 않으며 각 요청은 Rep의 상태가 무엇이든간에 고려됩니다. 단점은 많은 IoC/IRep <A> 괴롭힘입니다.

B가 IRep <A>을 한 번 묻고 보유하고있는 것을 유지하도록 Lazy <T> 패턴을 사용하려고 생각합니다. A가 저장소에서 삭제되면 어떻게됩니까?

변경된 내용을 관심있는 사람에게 알리기 위해 Rep <A>에 대한 명확한 방법을 찾고 있습니다. 예를 들어 특정 B의 A가 삭제 될 수 있으므로 Rep <A> 뭔가 삭제되거나 추가 될 때 이벤트를 발생 시키길 원합니다 Rep <B>이 이벤트에 가입하여 A를 참조하는 B를 정리할 수 있습니다. 이제 사라져 버렸어. 그걸 묶는 방법?

담당자 <A>을 인스턴스화 할 때 아무 것도 변경되지 않는 것이 이상적입니다. Reps를 발사하지 않고도 A가 하루 종일 조작 될 수 있습니다.

그러나 Rep <B이 태어난 경우 Rep <A> 이벤트에 가입해야합니다. Rep <A> 아직 살아있을 수는 없지만 B가 A에 대해 질문을 받으면 분명히 Rep <A>을 제기 할 것입니다.

본질적으로 Rep <B>가 인스턴스화 될 때 이벤트 알림을 위해 Rep <A>에 등록하려고합니다. Repository 레이어 외부의 누구에게도 영향을주지 않아야하므로 IRep <T> 인터페이스를 오염시키고 싶지 않습니다. 그리고 다른 유형의 저장소는 이것에 대해 전혀 염려 할 필요가 없습니다.

이 말이 맞는가요?

답변

3

Rep<A>을 A로 평가할 수있는 "관찰 가능"개체를 반환하고 A에 대한 무언가가 변경되면 발생하는 구독 가능한 이벤트가있는 경우 어떻게합니까? 그냥 생각. 이 방법을 사용하면 핸들러에서 A가 변경되었는지 확인하지 않아도됩니다. 그들이 듣고있는 사건이 해고된다면, 그 사건은 그 사건과 관련이 있으며 다른 사건은 아닌 것입니다. 다음과 같이

당신은 그것을 코딩 할 수 있습니다

public class Observable<T>:IDisposable 
{ 
    private T instance; 
    public T Instance 
    { 
     get{return instance;} 
     set{ 
     instance = value; 
     var handlers = ReferenceChanged; 
     if(handlers != null) handlers(this, instance); 
    } 

    public static implicit operator T(Observable<T> obs) 
    { 
     return obs.Instance; 
    } 

    //DO NOT attach anonymous delegates or lambdas to this event, or you'll cause a leak 
    public event EventHandler<T> ReferenceChanged; 

    public void Dispose() 
    { 
     var handlers = ReferenceChanged; 
     if(handlers != null) handlers(this, null); 
     foreach(var handler in handlers) ReferenceChanged -= handler; 
    } 
} 

public class Rep<T> 
{ 
    private Dictionary<T, Observable<T>> observableDictionary = new Dictionary<T, Observable<T>>(); 

    ... 
    public Observable<T> GetObservableFactory(Predicate<T> criteria) 
    { 
     //criteria should test only uniquely-identifying information 
     if(observableDictionary.Keys.Any(criteria)) 
     return observableDictionary[observableDictionary.Keys.First(criteria)]; 
     else 
     { 
     //TODO: get object from source according to criteria and set to variable queryResult 
     var observable = new Observable<T>{Instance = queryResult}; 
     observableDictionary.Add(queryResult, observable); 
     return observable; 
     } 
    } 
} 

... 

var observableA = myRepA.GetObservable(myCriteria); 
observableA.ReferenceChanged += DoSomethingWhenReferenceChanges; 

지금, 소비 코드는 내부 기준이 변경되는 경우 통보됩니다, 또는 관찰 (또한 내부 기준을 처분하는)에 배치된다.A 변경, A 자체를 관찰 할 수 있어야하는 관찰자에게 사용 코드를 알리려면 Observable<T>이 처리하는 이벤트를 발생시켜 ReferenceChanged 또는 InstanceDataChanged와 같은 특정 처리기를 통해 "버블 링"합니다 (또는 원하는대로).

+0

오 이런! 나는 약간의 실험을해야만하지만, 이것을 보는 좋은 방법이다. 감사합니다 키이스! – n8wrl