0

多層MVCプロジェクトでのインターフェイスと依存性注入の役割を理解するのに苦労しています。

プロジェクトには、WebCoreの2つのレイヤーがあります。

Coreには、すべてのエンティティ「IProjectDb」に対して定義されたインターフェイスがあります。 Webには、このインターフェース「ProjectDb」の実装があります。

  1. Coreプロジェクトのインターフェースはいつ使用されますか?EFがデータベースにアクセスできるように、インターフェイスを提供しますか?
  2. インターフェイスは、EFが実際のデータにアクセスできるように、Coreが実装されたバージョンにアクセスするために使用する単なるプロキシですか?
  3. もしそうなら、依存性注入はここでどのような役割を果たしますか?どのような依存関係(Webに依存するコア、コアに依存するWeb)、およびどこに、そしてなぜ注入するのですか?

インターフェイスの目標は、より良いテストのためにプロジェクトを分離することであることを理解しています。

ここで、このプロジェクトにサービスレイヤーを追加するとします。

  1. サービスレイヤーがすべてのデータアクセスを管理していると仮定すると、「ProjectDb」をサービスプロジェクトに移動できますよね?
  2. Webはサービスにアクセスする必要があります...したがって、サービスプロジェクトに実装されるWebプロジェクトにインターフェイスを作成する必要があると考えています。別の質問では、これは間違っており、インターフェイスと定義の両方がサービスレイヤーに存在する必要があると言われました。これは、インターフェイスの目的を損なうものです。誰かが私のためにこれを明確にすることができますか?
4

2 に答える 2

2

Coreプロジェクトのインターフェースはいつ使用されますか?EFがデータベースにアクセスできるように、インターフェイスを提供しますか?

ProjectDbはIProjectDbの具体的な実装の1つであるため、技術的にはすでに使用されています。IProjectDbを使用することで、単体テストをサポートするためのさまざまな追加の実装を提供したり、さまざまな展開シナリオでさまざまなデータストアを使用したりできます。

これには、実装を指定する手段(依存性注入または明示的)を提供する必要があります。

public HomeController : Controller
{
    private IProjectDb _projectDb;

    public HomeController() : this(new ProjectDb())
    {}

    public HomeController(IProjectDb projectDb)
    {
        _projectDb = projectDb;
    }

    ...
}

これはEFとは関係ありません。IProjectDb実装はEFを使用できますが、この方法では、コントローラーはEFを使用するかどうかを気にしません。

インターフェイスは、EFが実際のデータにアクセスできるように、Coreが実装されたバージョンにアクセスするために使用する単なるプロキシですか?

インターフェイスは、実装が従わなければならないコントラクトを定義しているだけです。上記のControllerの例を使用するIProjectDb _projectDbと、の実際の実装に関係なく、プロパティを一貫して使用できますIProjectDb。繰り返しますが、これはEFとは関係ありません。

もしそうなら、依存性注入はここでどのような役割を果たしますか?どのような依存関係(Webに依存するコア、コアに依存するWeb)、およびどこに、そしてなぜ注入するのですか?

依存性注入を使用すると、コンパイル時にハードコードされた実装を定義するのではなく、実行時に使用されるIProjectDbの実装を定義できます。それを持っている主な理由はユニットテストをサポートすることですが、それはそれに限定されません。

サービスレイヤーがすべてのデータアクセスを管理していると仮定すると、「ProjectDb」をサービスプロジェクトに移動できますよね?

はい。ただし、これをCoreに配置することも有効です(Coreがクラスライブラリであると想定しています)。必要に応じて他の場所で実装を使用できるようになるため、クラスライブラリを使用することをお勧めします。つまり、同じデータストアでバックグラウンドタスクを実行するために別のサービスを提供する必要がある場合は、Coreを参照して、同じ実装を再利用できます。

Webはサービスにアクセスする必要があります...したがって、サービスプロジェクトに実装されるWebプロジェクトにインターフェイスを作成する必要があると考えています。別の質問では、これは間違っており、インターフェイスと定義の両方がサービスレイヤーに存在する必要があると言われました。これは、インターフェイスの目的を損なうものです。誰かが私のためにこれを明確にすることができますか?

Webプロジェクトでインターフェースを作成すると、サービスの厄介な依存関係が作成され、層/レイヤーを分離する目的が無効になります。素人の言葉で言えば、あなたはサービスがWebアプリケーションに依存していると言っていますが、そうではないはずです。Webアプリケーションはサービスに依存する必要がありますが、サービスは必ずしも誰がそれを使用しているかを気にする必要はありません。

インターフェイスの目的は、定義されたコントラクトの複数の実装をサポートすることであり、サービスプロジェクトで定義することによって違反することはありません(サービスプロジェクトは通常、参照できない実行可能ファイルにコンパイルされるという事実を無視します)。

于 2013-02-19T06:00:35.060 に答える
0

おっしゃるように、インターフェースはCoreシステムとWebアプリケーションの間の関係を切り離すために使用されます。すべてのビジネスロジックをCoreプロジェクトのセグメント内に配置し、Webアプリケーションにこのビジネスロジックを使用させるとすると、インターフェイスは、で公開(または実装)するコントラクトを表しますCore

あなたの質問のそれぞれに答えて:

1-コアプロジェクトのインターフェイスはいつ使用されますか?EFがデータベースにアクセスできるように、インターフェイスを提供しますか?

アプリケーションWebは、インターフェイスを使用(または消費)し、IBusinessLayer(Entity Frameworkを介して)データストアへのアクセスを公開するアプリケーションです。

2-インターフェースは、EFが実際のデータにアクセスできるように、Coreが実装されたバージョンにアクセスするために使用する単なるプロキシですか?

はい。ただし、この場合はIDataAccessObject、によって実装される別のインターフェイス、、について話していることになりますEFDataAccessObjectOtherORMDataAccessObjectここでの考え方は、将来、実装のように別のORMに切り替えてIDataAccessObject、プロジェクトの残りの部分(CoreおよびWeb)を変更しないようにすることです。

3-もしそうなら、依存性注入はここでどのような役割を果たしますか?どのような依存関係(Webに依存するコア、コアに依存するWeb)、およびどこに、そしてなぜ注入するのですか?

依存性注入はまさにそれです。動的に構成および計算できる単一の具象型を登録することにより、これらすべてのインターフェースの実装を注入する方法です。基本的に、それぞれについて、

public WebClass
{
    public IBusinessLayer BusinessLayer { get; set; } // <-- Dependency
}

public BusinessClass
{
    public IProjectDB ProjectDB { get; set; } // <-- Dependency
}
... 

public Main()
{
    DependencyInjector
        .Register<IBusinessLayer>().With<ConcreteBusinessLayer>().
        .Register<IProjectDB>().With<EntityFrameworkProjectDB>();
}

..。

1-サービスレイヤーがすべてのデータアクセスを管理していると仮定すると、「ProjectDb」をサービスプロジェクトに移動できますよね?

はい。システムをレイヤーCoreの依存関係にするだけです。Service

public ServiceClass
{
    public IBusinessLayer BusinessLayer { get; set; } // <-- Dependency
}

public WebClass
{
    public IServiceLayer ServiceLayer { get; set; } // <-- Dependency
}

ご覧のとおり、Coreレイヤーの実装とは変更されておらず、依存関係をからにProjectDB移動して、レイヤーに依存関係を作成しただけです。BusinessWebServiceServiceWeb

2-Webはサービスにアクセスする必要があります...したがって、サービスプロジェクトに実装されるWebプロジェクトにインターフェイスを作成する必要があると考えています。別の質問では、これは間違っており、インターフェイスと定義の両方がサービスレイヤーに存在する必要があると言われました。これは、インターフェイスの目的を損なうものです。誰かが私のためにこれを明確にすることができますか?

これは前の質問と一致します:IServiceLayerインターフェースはServiceレイヤープロジェクトで定義され実装されています。このインターフェースを使用してWebレイヤーからサービスを利用しますが、これは依存関係にすぎません。

public WebClass
{
    public IServiceLayer ServiceLayer { get; set; } // <-- Dependency
}
于 2013-02-19T06:18:20.690 に答える