문제

나는 모델과 구현을 가능한 한 느슨하게 연결하려는 상황이 있지만, 커플 링이 내가 원하는 것보다 훨씬 가까워 질 수있는 상황에 직면하고 있습니다.

모든 인터페이스를 구현하는 '모델'클래스를 선택했습니다. 또한 '데이터 액세스'클래스가 있으며, 그 중 하나는 정수 조회 값을 전체 '개체'표현으로 디코딩하는 기능을 제공합니다.

모델 클래스 내에서 모델이 데이터 액세스 클래스에 대해 알지 않고도 해독 된 값에 대한 액세스를 제공하고 싶습니다.

단순화 된 예는 다음과 같습니다.

/// Core classes --

class Car : ICar
{
    public int MakeId { get {...} set { ... } }

    public IMakeInfo Make { get {...} }

    public string Registration { get { ... } set { ... } }

    public int CurrentOwnerId { get { ... } set { ... } }

    public IPerson CurrentOwner { get { ... } }
}

class MakeInfo : IMakeInfo
{
    public string Name { ... }
    public int Id { ... }
    public decimal Weight { ... }
    // etc etc
}

/// Data Access Classes --

class ResolveMake 
{
    public IMakeInfo GetMakeInfo(int id)
    { 
        // Implementation here...
    }

}

어떻게 활성화합니까? Car 제공하는 수업 IMakeInfo ResolveMake 클래스를 직접 알리지 않고 소비 클래스에 반대합니까? 실제 경우 자동차 클래스와 함께 작업하는 것은 ResolveMake 클래스와 동일한 네임 스페이스에 있지 않으며 인스턴스에 대한 참조가 포함되어 있지 않습니다.

내 옵션 중 일부 :

  • 대의원을 구현하십시오 Car 인스턴스와 함께 제공 될 수 있습니다 GetMakeInfo 방법.
  • 어떤 종류의 의존성 주입
  • 자동차를 밀접하게 부부와 함께 해결하고 완료합니다.
  • 다른 옵션이 있습니까?

모든 제안을 환영합니다!

도움이 되었습니까?

해결책

확장 방법?

namespace CarStuff
{
   class Car : ICar
   {
      public int MakeId { get {...} set { ... } }
      // no Make property...
      public string Registration { get { ... } set { ... } }
      public int CurrentOwnerId { get { ... } set { ... } }
      public IPerson CurrentOwner { get { ... } }
   }
}


namespace MakeExts
{
   class ResolveMake
   {
      public static IMakeInfo Make(this Car myCar)
      {
         //implementation here
      }
   }
}

다른 곳 :

using MakeExts;

Car c = new Car();
Console.WriteLine(c.Make().ToString());

편집 : .NET 2.0에서 확장 방법을 사용하려면 다음과 같은 것이 필요합니다.

기본적으로 포함 된 클래스 :

namespace System.Runtime.CompilerServices 
{ 
   class ExtensionAttribute : Attribute
   {
   }
 }

및 관련 장소에 흩어져있는 "System.Runtime.comPilerServices"를 사용합니다.

다른 팁

나에게 의존성 주입처럼 들린다. 나는 MS PP Unity와 비밀 기관 주입뿐만 아니라 방법 및 재산 주입과 비슷한 일을했습니다. 그러면 자동차 수업은 Imakeinfo를 주사합니다 ... 예 :

[InjectionMethod]
public void Initialize([Dependency] IMakeInfo makeInfo)
{
  this.MakeInfo = makeInfo;
}

자동차 클래스에는 imakeinfo를 반환하는 속성이 있기 때문에 이미 정보를 제공하는 것처럼 보입니다. 그렇다면 나는 당신의 문제가 자동차에 반품 할 가치가 어떻게 제공되는지 더 많이 가정 할 때 맞습니까?

이것이 사실이라면 아마도 당신은 아마도 공장 방법 자동차와 Resolvemake에 대해 알고 있습니다.

당신의 비유로 가면, get_make가 imakeinfo가 무엇인지 불러야 할 때까지 자동차는 분명히 알아야합니다. 나는 또한 자동차의 핵심 특성을 고려할 것입니다. 따라서 Imakeinfo를 자동차 생성자 (IOC를 사용하는)에 전달하는 것은 매우 합리적이라고 생각합니다. 이것이 당신의 실제 코드와 유사하다면 (각 "자동차"는 단일의 내재적 인 "Imakeinfo"를 가지고 있다면, 나는 이것과 함께 갈 것입니다.

Johan과 같은 세터를 사용할 수도 있습니다. 제가 생성자를 선호하는 이유는 모든 "자동차"는 "제작"이 있어야합니다.

결국 (내가 내부에서 일하고 있던 제약 조건을 감안할 때) 실제로 위의 여러 주제에 대한 변형을 사용했습니다.

순환 참조로 인해 내 데이터 액세스 계층에 대한 참조를 피해야했기 때문에 대의원 및 '공장'코드와 무언가를하게되었습니다. 원래 시나리오에 맞추면 다음을 수행했습니다.

class Car 
{
    public void SetLookupProvider(ILookupProvider value) { _lookupProvider = value; }

    public IMakeInfo Make { get { return _lookupProvider.ResolveMake(MakeId); } }

    ....
}

interface ILookupProvider
{
    IMakeInfo ResolveMake(int id);
}

class LookupProvider
{
    public delegate IMakeInfo ResolveMakeDelegate(int id);

    public ResolveMakeDelegate ResolveMakeDel { set { _resolvemake = value; } }

    public IMakeInfo ResolveMake(int id){ return _resolvemake(id); }  
}

그런 다음 내 공장 방법에서 ...

ICar returnedObject = new Car(blah, foo, bar, etc);

ILookupProvider luprovider = new LookupProvider();
luprovider.ResolveMakeDel = DataAccessLayer.FunctToGetMakeInfo;

(Car)returnedObject.SetLookupProvider(luprovider).

이제 나는 이것이 가장 아름다운 솔루션이 아니라는 것을 인정하는 첫 번째 사람입니다 (3.0 컴파일러에 액세스하면 확장 방법으로 갔을 것입니다.) 내 상황은 원형 참조 지옥을 막았다 ...). 자동차 클래스는 결과가 어떻게 발생하는지 알 필요가 없으며, 먼저 자동차 객체를 생성하는 공장 방법은 데이터 액세스 계층에 연결된 유일한 것입니다.

나는 아직 대답을 표시하지 않았다. 나는 몇 명의 사람들이 더 많은 투표를 한 다음 가장 높은 것으로 보이게 할 것이다. 특히 나는 그들이 모두 유효한 대답이라고 생각하기 때문에 (이 경우에도 완전히 사용할 수 없다는 것입니다). .

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top