3

満足のいく答えを見つけることができなかった MVC アプリでの依存性注入に関する基本的な質問であることを願っています。私のアプリは、MVC 3 プロジェクト、サービス レイヤー クラス ライブラリ (SL)、およびデータ アクセス クラス ライブラリ (DAL) で構成されています。SL と DAL の両方に、それぞれのインターフェイスと実装が含まれています。MVC プロジェクトは、SL プロジェクトと DAL プロジェクトの両方を参照します。MVC プロジェクトは DAL の実装を作成し、それを DAL インターフェイスを受け入れる SL コンストラクターに挿入します。

私が懸念しているのは、SL が DAL インターフェイスをパラメーターとして受け入れるためには、DAL プロジェクトへの参照も必要である (インターフェイスがたまたま存在するだけでなく、実装もある) ことです。これは、現在 MVC とSL プロジェクトには、DAL アセンブリへの参照が必要です。

簡単に言えば、SL が実装プロジェクトではなくインターフェイス プロジェクトのみを参照する必要があるように、DAL インターフェイスを独自のプロジェクトに移動する方が理にかなっているでしょうか? MVC プロジェクトは明らかにインターフェイス プロジェクトと実装プロジェクトの両方を参照する必要があり、DAL はインターフェイス プロジェクトも参照する必要があります。これは、私のソリューションに別のプロジェクトを追加しても、物事を行うためのよりクリーンな方法のように思えますが、それほど気になりません。SL 内に DAL インターフェイスを格納し、DAL 参照 SL を持つという提案も見ましたが、それは私には正しくないようです。洞察や提案をいただければ幸いです。ありがとう!

4

4 に答える 4

5

タマネギのアーキテクチャを見てみましょう。

http://jeffreypalermo.com/blog/the-onion-architecture-part-1/

http://jeffreypalermo.com/blog/the-onion-architecture-part-2/

http://jeffreypalermo.com/blog/the-onion-architecture-part-3/

UI アセンブリがすべてのサービスおよびビジネス ロジック アセンブリへの参照を持っていてもまったく問題ありません。サービス層は明らかに、より高いレベルに依存すべきではないインフラストラクチャ アセンブリを参照する必要があります。

于 2012-09-02T03:48:30.857 に答える
2

真のコンポーネントは、インターフェイスと実装が別々のアセンブリにある必要があります。

これにより、適切な実装をアドインのように動的にロードできます。多くの場合、循環参照を回避する唯一の方法でもあります。例として、DAL はモデル (ビジネス クラス) を知る必要があり、モデルは DAL 呼び出しを介して依存モデルを遅延読み込みする必要がある場合があります。これにより、循環参照が作成されます (.NET は循環アセンブリ参照を禁止します)。インターフェイスが別々のアセンブリにある場合、DAL アセンブリとモデル アセンブリの両方が両方のインターフェイス アセンブリへの参照を持ち、コンストラクターを介して注入された依存関係を取得します。

// Assembly: Model contracts

public interface IModelA
{
    IModelB ModelB { get; }
    ...
}

public interface IModelB
{
    ...
}

public interface IModelFactory
{
    IModelA CreateModelA();
    IModelB CreateModelB();
}

// Assembly: DAL contracts, references Model contracts

public interface IDAL
{
    IModelA LoadA(int id);
    IModelB LoadB(int id);
}

// Assembly: Model implementation, references Model and DAL contracts

public class ModelA : IModelA
{
    private IDAL _dal;

    public ModelA (IDAL dal)
    {
        _dal = dal;
    }

    private IModelB _modelB;
    public IModelB ModelB
    {
        get {
            if (_modelB == null) {
                _modelB = _dal.LoadB(5);
            }
            return _modelB;
        }
    }
}

// Assembly: DAL implementation, references Model and DAL contracts

public class DAL : IDAL
{
    private IModelFactory _modelFactory;

    public DAL(IModelFactory _modelFactory)
    {
        _modelFactory = modelFactory;
    }

    public IModelA LoadA(int id)
    {
        IModelA modelA = _modelFactory.CreateModelA();
        // fill modelA with data from database
        return modelA;
    }

    public IModelB LoadB(int id)
    {
        IModelB modelB = _modelFactory.CreateModelB();
        // fill modelB with data from database
        return modelB;
    }
}
于 2012-09-02T15:21:17.520 に答える
1

ルールが言うように、具体的な実装ではなくインターフェースに依存している限り、それは問題ありません。したがって、できることは、インターフェイスを別々のアセンブリに配置し、必要な場所でそれらを参照することです。

于 2012-09-02T04:04:05.910 に答える
1

具象型を含むアセンブリを参照することは問題になる可能性がありますが、達成しようとしていることに依存します。サービスを抽象化のみに依存させることで、疎結合コードを実現できます。これにより保守性が向上します。

BL アセンブリが抽象化を含む (実装は含まない) アセンブリのみを参照できるようにすると、ソフトウェアの一部を個別に展開できます。たとえば、ソフトウェアをさまざまな顧客に展開したいと考えており、DA レイヤーにはいくつかのフレーバーがありますが、すべての DA フレーバーをすべての顧客に展開したくないとします (たとえば、DA レイヤーごとに支払う必要があるため、またはおそらくあなたはあなたの知的財産を保護しようとします)。

そのため、展開で分離が問題にならない場合は、個別のアセンブリを作成する必要はありません。

于 2012-09-02T14:42:59.200 に答える