2

가능한 중복 :
StructureMap singleton usage (A class implementing two interface)IoC 컨테이너를 사용할 때 인터페이스 분리를 ​​관리하는 방법은 무엇입니까?

나는 현재 작은 시스템을 설계하고 있는데 내가 현재 IOC의로 structureMap을 사용하고 있습니다. 방금 인터페이스 분리의 요지가 생겼어. 지금 궁금해.

특정 비즈니스 객체가 있으면 구현할 수있는 인터페이스가 3 개 ... 코드의 구성 및 instatiation에서 어떻게 처리해야합니까?

간단한 시나리오에서는 EmployeeServiceObject라는 서비스 계층 클래스에 대해 두 개의 인터페이스가 있다고 가정합니다. IGenericEntity 및 IEmployeeServiceObject입니다.

GenericEntity는 클래스에 CRUD 기능을 제공하고 IEmployeeServiceObject는 비즈니스 쿼리/작업에 대한 결과 집합을 제공합니다.

Facade/Service Layer 메서드에서 EmployeeServiceObject 클래스를 사용해야하고 실제로 두 인터페이스의 기능을 사용해야합니다. 어떻게 처리해야합니까?

처음에는 올바른 작업은 IoC의 구성을 설정하여 IEmployeeServiceObject를 EmployeeServiceObject에 매핑하고 개체에 대한 팩토리를 요청한 다음 CRUD 기능을 사용해야 할 때 IGenericEntity로 캐스팅했지만, 모르겠다. 또한 구체적인 클래스가 실제로 ioc 컨테이너 구성에서 설정되지 않은 인터페이스를 구현한다는 사실을 공식적으로 밝히지 않기 때문에 옳지 않은 것처럼 보입니다.

그리고 나는 분명히 동일한 구체적인 클래스의 두 인스턴스를 생성하지만 다른 인터페이스를 요청하는 것은 더욱 악해진다는 것을 알고 있습니다.

어떻게 처리해야합니까? 그렇다면

public interface IGenericEntity { /**/ } 

public interface IEmployeeServiceObject { /**/ } 

public class EmployeeServiceObject : IEmployeeServiceObject, IGenericEntity 

이 EmployeeServiceObject이 두 인터페이스를 구현한다는 사실이 구현 세부입니다 : 내가 제대로 질문을 이해한다면

+0

안녕, 나는 StructureMap에서이 작업을 수행하는 방법의 세부 사항을 알고하지 않습니다,하지만 당신은 여러 인터페이스와 클래스를 등록 할 수 있어야한다. 그런 다음 인터페이스를 요청할 때 단일 인스턴스를 검색하도록 단일 범위를 설정할 수 있습니다. –

+0

감사합니다 샘. 난 그냥 어떻게 해야할지 알고 싶다 StructureMap ..이 방법은 내가 어떤 IoC 컨테이너와 함께 처리 될지 찾고 있는데 ... 그것을하는 방법의 원칙. – GR7

답변

0

나는 중복으로 내 질문을 닫는 방법을 찾지 못했지만 ... 정확히 내가 어떻게 다른 stackoverflow 질문에 필요한 일을 발견.

Windsor에서 Forward 메서드로 언급 한 Mark는 StructureMap에도 존재하며 올바른 방법 일 것입니다.

StructureMap singleton usage (A class implementing two interface)

2

, 당신은 (C# 코드)에 다음과 같은 시나리오를 가지고있다. 각 인터페이스를 별도로 구현하는 다른 구현이있을 수 있습니다. ISP에의

요점은 각 인터페이스 모델을 별도의 우려, 당신은 자주 당신이 IGenericEntity 및 IEmployeeServiceObject 모두 당신이 두 개의 인터페이스로 분리가 의미인지 질문해야해야하는 상황에 처할 수 그래서 만약.

그렇지 않으면 캐스팅 시도시 Liskov Substitution Principle이 깨질 수 있으므로 각 인터페이스를 별도로 요청해야합니다.

당신이 진정으로 모두를 필요로하는 경우에, 당신은 모두 요청해야합니다 : 두 인터페이스를 구현하는 당신은 하나 개의 클래스 (EployeeServiceObject)를 가지고있는 경우

public class Foo 
{ 
    public Foo(IGenericEntity ge, IEmployeeServiceObject eso) { /**/ } 

    // ... 
} 

을, 당신은 DI 컨테이너를 이야기해야합니다 이것이 사실입니다. 이 시점에서 우리는 콘테이너 특정 세부 사항의 지역으로 이동하고있다, 그래서 어떻게하면 당신은 각 콘테이너에 따라 다르다.

예를 들어, Windsor에는 한 인터페이스의 요청이 다른 유형으로 전달되도록 지정하는 Forward 메소드가 있습니다. 그것은 당신에게 어떻게 용기에 중요한 단서를 제공 할 수 있기 때문에 당신이 가난한 사람의 DI와 종속성 계층 구조를 구성 할 방법을 이해하는 좋은 일이 항상 간단

var eso = new EmployeeServiceObject(); 
var f = new Foo(eso, eso); 

가난한 사람의 DI 그것은이다 똑같은 것을 이해할 것입니다.

+0

Mark, 동일한 방법으로 두 인터페이스 (동일한 개체로 구현 됨)의 메서드를 사용해야하는 시나리오가 나온다면 좋은 점을 알게 될 것입니다. 가장 최적이고 어쩌면 두 가지 방법 모두 동일한 인터페이스에 속해야합니다. 내가 캐스팅하면 Liskov의 원칙을 어기는 것에 동의합니다.그리고 그 시나리오에서 컨테이너와 함께 구체적인 클래스를 각 인터페이스에 대해 두 번 등록하려고하는지조차 알지 못했습니다. – GR7

+0

당신이 언급 한 것처럼 시나리오가 분명히 필요한 곳으로 가야한다면, 생성자에서 두 가지 의존 관계를 모두 언급하는 것이 길이다. 이제 특정 IoC 컨테이너 구현으로 이동하여 동일한 구체화 구현이 두 인터페이스에 모두 매핑되는지, 인스턴스를 재사용 할 것인지, 내부적으로 두 번째 인터페이스로 형변환되는지를 확인합니다. 가난한 사람의 DI로 어떻게 수행 될지 생각해 보는 것에 대해 매우 좋은 설명입니다. – GR7

0

DI/IoC 구현을 해결하기 전에 API를 설명하고자합니다. 나는 당신의 고통 점이 당신을 더 나은 디자인으로 이끌려고 노력하고 있다고 생각합니다.

EmployeeServiceObject가 너무 많은 책임이있는 것으로 보입니다. 개체를 만드는 동안 Single Responsibility Principle을 고려하십시오. 설명에서 EmployeeServiceObject는 모두 외관/서비스 계층 CRUD 계층입니다. CRUD 작업을위한 인터페이스 (IGenericEntity)를 할당하면 CRUD 구현을 외관 (IEmployeeServiceObject)의 소비자에게 노출하게됩니다.

당신이 설명한이 상황과 유형, (나는 또한 더 정확하게 자신의 목적 설명하기 위해 당신의 유형 이름을 재고 할 ) 다른 접근 방법을 고려하시기 바랍니다 감안할 때 :

public interface IEmployeeServiceObject 
{ 
    // Service methods 
    decimal GetSalary(string employeeId); 
} 

public class EmployeeServiceObject : IEmployeeServiceObject 
{ 
    private IGenericEntity<Employee> _entity; 

    public EmployeeServiceObject(IGenericEntity<Employee> entity) 
    { 
     _entity=entity; 
    } 

    public decimal GetSalary(string employeeId) 
    { 
     return _entity.Get(employeeId).Salary; 
    } 
} 

public interface IGenericEntity<T> 
{ 
    // CRUD Methods including... 
    T Get(string id); 
} 

public class GenericEntity<T> : IGenericEntity<T> 
{ 
    T Get(string id){...} 
} 

IEmployeeServiceObject/EmployeeServiceObject 등록을하고 IGenericEntity/GenericEntity가 선택한 컨테이너와 쌍을 이룹니다. (StructureMap은 규칙에 따라 이러한 형식을 등록 할 수 있습니다.)

컨테이너에서 IEmployeeServiceObject를 요청하면 컨테이너는 GenericEntity를 제공하기 전에 GenericEntity를 EmployeeServiceObject의 생성자에 삽입합니다.

이렇게하면 설명한 캐스팅/등록 문제를 피할 수 있습니다. 컨테이너가 최적 이하의 방식으로 작동하도록 할 필요가 없습니다. 또한 귀하의 정면은 고객이 필요로하는 것을 드러내고 CRUD 작업을 다른 클래스 (고객에게 노출 될 필요가 없음)로 연기합니다.

+0

마크. 다른 접근법을 제안 해 주셔서 감사합니다. 실제로 디자인이 최적이 아니라고 말하는 것이 옳습니다. CRUD 기능은 서비스 계층에 공개해서는 안되지만, 내 생각과 비슷합니다. 디자인이 완전히 유효하고 필자가 제공 한 샘플 시나리오에서 가장 좋은만큼 프로그래머가 동일한 개체의 두 인터페이스에서 메서드를 사용해야 할 수도있는 시나리오가 있다고 생각합니다. 컨테이너), 그리고 어떻게 처리해야하는지 알고 싶습니다. – GR7

+0

유효한 기술적 인 질문이지만 클라이언트가 인터페이스가 동일한 클래스에 의해 구현되는지 여부를 아는 것이 Liskov 위반 (나는 우리가 모두 친구들 사이에서 단호하게 말할 수 있다고 가정합니다)이 아닙니까? 구현 세부 정보가 클라이언트로 누출되는 것 같습니다. –

관련 문제