2

重複の可能性:
依存性注入は循環依存を防ぐことができますか?

dal、SharePointとの統合、例外処理などのさまざまなサービスを提供するフレームワークを開発しています。

私はIoCでそれを行う必要があり、私はこのアプローチに不慣れです。[私がどのように行っているかについて循環参照があるようです]

だから私の意見では、3つのタイプのプロジェクトがあります

  • インターフェース:できれば別のプロジェクト
  • インターフェイスを実装する具体的なクラスプロジェクト(例外、dal、統合などのサービスプロジェクト)
  • bootstrapper \ conifiguration(configurator):できれば別のプロジェクト。「インターフェース」プロジェクトにある場合、IoCはインターフェースと具象クラスの両方の参照を必要とするため、具象クラスプロジェクトとの循環参照を作成します。

今ここにあるものです

  1. 具象クラスは、循環参照を作成することになるため、他の具象クラスの参照を持つべきではありません(循環参照がある場合、IoCの目的全体が失われるのではないでしょうか、それともここで間違っていますか?)。

  2. 次に、開始プロジェクト(単体テスト、WCFサービスなど)は、最初にブートストラッパーをロードしてすべてのタイプを登録する必要があるため、スタートアッププロジェクトにブートストラッパープロジェクトを追加する必要があります。ユニティコンテナーのインスタンス[シングルトン]を作成して、すべてを登録します。タイプ。タイプを解決するには、他のすべてのサービスプロジェクトで同じインスタンスが必要です。

そのため、タイプ解決のためにブートストラッパープロジェクトをサービスプロジェクトに追加する必要があります。このアプローチは、ポイント1で述べたのと同じ問題が発生するため、正しくありません(すべてのサービスプロジェクトには、サービスプロジェクトの参照が含まれます)。

それについてどうやって行くのですか?登録時のプロパティインジェクションにより、各具象クラスのプロパティとしてUnityContainerを追加してみました。これが正しい方法かどうかさえわかりません。私の主な関心事は、結果を達成するためのベストプラクティスです。したがって、これをガイドしていただければ、本当に感謝しています...

前もって感謝します!

パフォーマンス、構成、コード内タイプの登録、またはインスタンス登録のどちらの方法を好むか、もう1つありますか?

必要に応じて、デモプロジェクトをアップロードできます。私は一つのことを説明することができます。Dalは例外マネージャーを使用し、例外マネージャーはユーザーフレンドリーなメッセージにトランスレーターを使用し、トランスレーターはユーザーフレンドリーなメッセージを取得するためにDALを使用します。これは、循環参照がある1つのケースです。しかし、お互いに参照を追加すると、多くのことがあります。

[更新-サンプルコードが含まれています]IoCはまだ実装されていないため、IoCへの参照は表示されません。publicbool Update(){
bool result = false;

        //Central DB
        IDataServiceManager oDataServiceMgr = null;
        DbTransaction oTrans = null;

        //Client DB
        IDataServiceManager oDataServiceMgrClient = null;
        DbTransaction oTransClient = null;

        try
        {

            oDataServiceMgr = new DataServiceManager(); //Connets to Centeral DB
            oTrans = oDataServiceMgr.BeginTransaction();

            if (this.UpdateUserData(oDataServiceMgr, oTrans))  //First Update in Center
            {
                oDataServiceMgrClient = new DataServiceManager(this.clientIDField); //Connects to client db
                oTransClient = oDataServiceMgrClient.BeginTransaction();
                if (this.UpdateUserData(oDataServiceMgrClient, oTransClient))
                    result = true;
            }

            if (result)
            {
                oTrans.Commit(); //Center DB
                oTransClient.Commit(); //Center DB
            }


        }
        catch (UserServiceException ex)
        {
            this._UserServiceException = new UserServiceException();
            SnapFlow.ExceptionHandling.ExceptionHandler.Wrap(this._UserServiceException, ex, true);
            throw this._UserServiceException;
        }

        finally 
        {
            if (!result && oTrans != null)
                oTrans.Rollback();

            if (!result && oTransClient != null)
                oTransClient.Rollback();

        }

        return result;
    }
4

2 に答える 2

4

循環参照と同様に、コード自体の実際のアーキテクチャを確認する必要があります。IoC/DI はさておき、循環参照が発生している場所を調べてリファクタリングしてください。これらの参照は本当にそこにある必要がありますか? より使いやすいデザインはありますか?

于 2011-03-14T08:37:05.157 に答える
1

注:私はあまり知りませんUnityが、他のiocコンテナーと連携しました

私があなたを正しく理解していれば、循環参照を避けるためにプロジェクトをレイアウトする方法を知りたいと思うでしょう。私の意見では、これらのプロジェクト(dll)が必要です

  • すべてのインターフェイスを含むWaqas.Base.dll。団結やその他のWaqas。*。dllへの依存はありません
  • Waqas.Base.dllのみに依存するサービス、dal、...(つまり、Waqas.Service.Payment.dll)の実装を含む1つ以上のdllは、単一性に依存しません
  • Waqas.Base.dllおよび他のすべてのWaqas。*。dllを認識する1つのBootstrapperコンポーネント(理想的には1つのメソッドのみ)。その唯一の責任は、システムを配線することです。これは、団結を知っている唯一のコンポーネントです。
  • メインアプリケーションと統合テストはブートストラッパーを使用します。
  • ユニットテストがある場合は、services、dal、...をモックに置き換えて手動でテストを接続します。

(更新)例

waqas.service.paymentは、ブートストラッパーまたはユニティを参照せずにdalにアクセスする必要があります。

古いバージョンからの変更

    public class PaymentService
    {
        public PaymentService();

        SavePayment( ...)
        {
                         IDAL dal = ioCContainer.resolve<IDAL>();
                         dal.Save(...);
        }
    }

新しいバージョンへ

    public class PaymentService
    {
        IDAL theDal;
        public PaymentService(IDAL dal) {theDal = dal;};

        SavePayment(...)
        {
             theDal.Save(...);
        }
    }

ブートストラッパーは、DalとPaymentServiceを作成し、それらを相互に接続する役割を果たします。IDalはWaqas.Base.dllで定義されています。

于 2011-03-14T08:34:13.783 に答える