2

私は複雑なビジネスのプロジェクトに取り組んでいます。 AccountServiceとSchoolServiceの2つのクラスを考えてみましょう。Anemicドメインモデルを使用したサービス間の循環参照

私はUnityとWeb 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) 
    { 
     ... 
    } 
} 

2つのクラスがお互いを参照している、これは、プロジェクト内のBLCの70%のための状況です。

+0

プロジェクトでこのような循環依存性の例を挙げることはできますか。 – user1849310

+4

貧しいデザインのような音...私は3番目のサービスに共通のものを打ち破るだろう。それは循環依存を解決します。 DIエンジンは通常、循環参照で例外をスローします。 – SledgeHammer

+0

@SledgeHammerその他のポイント。あなたはDIなしでも問題をどのように解決しますか? DIは魔法ではありません。もしあなたがそれなしではできないなら、あなたはそれを行うことができません。 – Aron

答えて

0

このようにすれば、IoCロジックを実行するインターフェイスを持つことができ、それをUnityの解像度をラップする実装に解決できます。

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

次に、あなたは、コンストラクタで両方のサービスにそのインターフェイスを通過して、あなたがそれを使用する前に、コンストラクタの外に、他のサービスをレイジー解決にそれを使用することができます。プロジェクトがある

:ところで両方のサービスが初期化されたとき、彼らは@KMoussaではなく、いくつかの変更を示唆したように、私がどうなるだけITypeResolver

0

に、他のサービスに直接依存関係を持っていません

貧血モデルを使用するので、コンテキストパターンを使用して遅延ロードを行い、任意のサービスを作成し、コンテキストをパラメータとしてサービスコンストラクタに渡します。

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