2017-11-29 12 views
1

DTO를 사용하여 영구 클래스 대신 데이터 크로스 레이어/어셈블리를 전달하려는 경우 영구 모델의 클래스에 대한 액세스를 동일한 어셈블리 내의 개체로 제한 할 수 있습니다. 의존성 주입은 "내부"일 수있는 클래스의 범위를 확대합니까?

그러나 오차드 CMS와 같은 시스템의

(ORM에 대한 자 NHibernate를 사용하고, 의존성 삽입 (Dependency Injection)에 대한 AutoFac)는, 지속성, IRepository<T>가 지속성을 위해, 시스템은 클래스 생성자 중 하나에 내 어셈블리에 IRepository<T>를 주입합니다 제공하는 다른 어셈블리를 통해입니다 따라서 영속 클래스 T가 공개되어야합니다. 의존성 삽입이 없으면 T를 내부로 정의하고을 내 어셈블리 코드 내에 활용할 수 있습니다. 의존성 주입을 사용하면 클래스가 항상 공개되어야합니까?

답변

1

예, 컨테이너가 주사 범위의 의존성이 public 확장되도록 it generally requires1 인스턴스화 공급 종속 할 수 있도록하기 위해서이다.

실제로, 종속성 변환 원칙의 또 다른 흔한 (그리고 잘못된) "gripe"은 이제 주입되는 모든 클래스의 내부 종속성이 일반적으로 공용 생성자에 노출된다는 것입니다. 원래 겉으로는 " 3 Amigos "OO의 교장, 이는 대중의 관점에서 단호하게 숨겨진 한 부류의 내부 의존성을 가졌습니다.

당연히이 클래스는 클래스를 종속성과 직접 결합하여 new 인스턴스화를 통해 디커플링을 방지하고 최악의 경우 혼란스런 시대 코드에서 첫 번째 클래스 설계 관심사로 인식됩니다.

규칙에 따라 클래스 간의 결합은 항상 인터페이스를 통해 이루어져야한다는 점을 기억해야합니다. 이러한 공용 클래스와 생성자를 실제로 "사용"하는 유일한 액터는 컨테이너 테스트와 유닛 테스트 일 것입니다. 예를함으로써

:

저장소 조립

public interface IFooRepo 
{ 
    Task<IEnumerable<Foo>> FindFoos(Predicate predicate); 
    // ... 
} 

// For IoC and testing purposes, MyFooRepo must be public 
public class MyFooRepo : IFooRepo 
{ 
    // .. Implement 
} 

서비스 조립

// Note : No indication of the IFooRepository dependency here 
public interface IMyService 
{ 
    Task DoAmazingThingsWithFoo(); 
} 

// MyService class must also be public for IoC and tests 
public class MyService : IMyService 
{ 
    private readonly IMyRepo _repo; 
    // Dependencies are publically visible on the constructor 
    public MyService(IMyRepo repo) 
    { 
     _repo = repo; 
    } 
    // ... Implement 
} 

IOC의 부트 스트랩

Bind<IFooRepo>().To<MyFooRepo>(); // Can also specify lifetimes etc 
Bind<IMyService>().To<MyService>(); 

추가 읽기 - Mark Seemann은 public scope을 방어합니다.


[1] 스티븐 넌 및 인터페이스에 대하여도 내 예 "비록 커플 링은 일반적으로 인터페이스 대하여 있어야"지적 SimpleInject의 주요 저자

+0

이지만, 인터페이스 자체에 결합 공용 클래스 (IRepository ), 따라서 커플 링이 인터페이스 대신 클래스에 대해 여전히 더 나은 방법으로 인터페이스를 유지할 수 있습니까? –

+0

다른 클래스에 종속 된 클래스는 인터페이스 (D의 SOLID)를 통해서만 연결되어야한다는 것을 의미합니다. IoC 부트 스트래핑 자체는 절대로 우아하지 않습니다. 일반적으로 인터페이스 종속성이 필요할 때 사용할 구체적인 클래스를 정의합니다 (일부 IoC는 명명 규칙을 기반으로 자동 바인딩됩니다). 나는 예제를 업데이트했다. – StuartLC