2

Ich arbeite an einem Projekt mit einem komplexen Geschäft. Betrachte zwei Klassen: AccountService und SchoolServiceCircular Referenz zwischen den Diensten mit dem Anemic-Domain-Modell

Ich verwende Unity und den Abhängigkeits-Resolver der Web-API, um die Abhängigkeitsinjektion im Konstruktor zu implementieren.

Der Schuldienst verwendet den Kontodienst bei einigen Methoden, auch der Kontodienst verwendet den Schulservice. All dies ist im Geschäft des Projekts erforderlich. Dies führt zu einer zirkulären Abhängigkeit, und es ist nicht möglich, die Methoden von einer Klasse in eine andere zu verschieben.

Können Sie mir bitte eine Idee geben, wie Sie das lösen können? Hier

ein Beispiel:

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) 
    { 
     ... 
    } 
} 

Die beiden Klassen einander verweisen, ist dies die Situation für 70% der BLCs im Projekt.

+0

Können Sie ein Beispiel für eine solche zyklische Abhängigkeit in Ihrem Projekt angeben. – user1849310

+4

Klingt wie ein armes Design ... Ich würde die üblichen Sachen zu einem 3. Dienst ausbrechen. Das wird die zirkuläre Abhängigkeit lösen. DI-Motoren werfen normalerweise eine Ausnahme auf einen kreisförmigen Bezug. – SledgeHammer

+0

@SledgeHammer Mehr auf den Punkt. Wie würdest du das Problem auch ohne DI lösen? DI ist nicht magisch, wenn du es ohne es nicht kannst, kannst du es nicht damit machen. – Aron

Antwort

0

Wenn Sie es unbedingt tun müssen, können Sie eine Schnittstelle haben, die Ihre IoC-Logik ausführt und diese in eine Implementierung auflöst, die die Auflösung von Unity umschließt, z.

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

Dann können Sie diese Schnittstelle für beide Dienste in den Konstruktor übergeben und es verwenden, um den anderen Service-faul-lösen, bevor Sie es benutzen, außerhalb der Konstruktor.

Auf diese Weise, wenn beiden Dienste initialisiert werden, werden sie auf dem anderen Dienst eine direkte Abhängigkeit nicht haben, nur auf ITypeResolver

0

Ich werde von @KMoussa aber mit einigen Änderungen wie vorgeschlagen tun:

Das Projekt ist Mit dem anämischen Modell werde ich ein Kontextmuster verwenden, um einen Service lazy zu laden und zu erstellen, und der Kontext wird als Parameter an den Service-Konstruktor übergeben.

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 
    } 
}