2

저는 복잡한 비즈니스를 수행하는 프로젝트를 진행하고 있습니다. AccountService와 SchoolService의 두 클래스를 고려하십시오.Anemic 도메인 모델을 사용하는 서비스 간의 순환 참조

저는 Unity와 웹 API의 의존성 해결자를 사용하여 생성자에서 종속성 삽입을 구현하고 있습니다.

학교 서비스는 일부 방법으로 계정 서비스를 사용하며 계정 서비스는 학교 서비스를 사용합니다. 이 모든 것은 프로젝트 사업에서 필요합니다. 이로 인해 순환 종속성이 생기고 한 클래스에서 다른 클래스로 메소드를 이동할 수 없습니다.

해결 방법에 대한 의견을 제시해주세요. 두 클래스가 서로를 참조하는

public class SchoolBLC : ISchoolBLC 
{ 
    public School GetSchool(int schoolId) 
    { 
     ... 
    } 

    public bool RenewRegistration(int accountId) 
    { 
     bool result = true; 

     IAccountBLC accountBLC = new AccountBLC(); 
     // check some properties related to the account to decide if the account can be renewed 
     // ex : the account should not be 5 years old 
     // check the account created date and do renewal 

     return result; 
    } 
} 

public class AccountBLC : IAccountBLC 
{ 
    public void ResetAccount(int accountId) 
    { 
     ISchoolBLC schoolBLC = new SchoolBLC(); 
     School accountSchool = schoolBLC 

     // get the school related to the account to send a notification 
     // and tell the school that the user has reset his account 
     // reset account and call the school notification service 
    } 

    public Account GetAccount(int accountId) 
    { 
     ... 
    } 
} 

이 프로젝트의 BLCs의 70 % 상황이다 : 여기

는 일례이다.

+0

프로젝트에서 순환 의존성의 예를들 수 있습니까? – user1849310

+4

가난한 디자인 같은 소리 ... 나는 일반적인 서비스를 제 3의 서비스로 분해 할 것입니다. 그것은 순환 종속성을 해결할 것입니다. DI 엔진은 일반적으로 순환 참조에서 예외를 throw합니다. – SledgeHammer

+0

@SledgeHammer 그 이상입니다. DI 없이도 어떻게 문제를 해결할 수 있습니까? DI는 마술 적이 지 않습니다. 만약 당신이 그것을하지 않으면 그것을 할 수 없다면, 그것을 할 수 없습니다. – Aron

답변

0

그런 식으로해야한다면 IoC 논리를 수행하고 Unity의 해상도를 래핑하는 구현을 해결할 수 있습니다. 생성자 외부에서 사용하기 전에

public interface ITypeResolver 
{ 
    T Resolve<T>(); 
} 

그럼 당신은 생성자에서 두 서비스 모두에 해당 인터페이스를 통과하는 데 사용할 수있는 다른 서비스를 게으른-해결.

두 서비스 만에, 그들은 다른 서비스에 직접적인 종속성이되지 않습니다 초기화 그런 식으로 ITypeResolver

0
@KMoussa이 아니라 몇 가지 수정을 제안 내가 할 것

:

프로젝트는 빈맥 모델을 사용하여 컨텍스트 패턴을 사용하여 지연로드하고 모든 서비스를 만들고 컨텍스트를 매개 변수로 서비스 생성자에 전달합니다.

public class SDPContext : ISDPContext 
{ 
    private ITypeResolver _typeResolver; 

    public Account CurrentUser { get; set; } 

    public IAccountService AccountService 
    { 
     get 
     { 
      // lazy load the account service 
     } 
    } 

    public ISchoolService SchoolService 
    { 
     get 
     { 
      // lazy load the schoolservice 
     } 
    } 

    public SDPContext(ITypeResolver typeResolver) 
    { 
     this._typeResolver = typeResolver; 
    } 
} 

public class ServiceBase 
{ 
    public ISDPContext CurrentContext { get; set; } 

    public ServiceBase(ISDPContext context) 
    { 
     this.CurrentContext = context; 
    } 
} 

public class AccountService : ServiceBase, IAccountService 
{ 
    public AccountService(ISDPContext context) : base(context) 
    { 

    } 

    public bool ResetAccount(int accountId) 
    { 
     // use base.Context.SchoolService to access the school business 
    } 
} 

public class SchoolService : ServiceBase, ISchoolService 
{ 
    public SchoolService(ISDPContext context) : base(context) 
    { 
     //this._accountService = accountService; 
    } 

    public void RenewRegistration(int accountId) 
    { 
     // use the base.Context.Account service to access the account service 
    } 
}