2012-05-16 30 views
33

私は、インターネットから読んだ私は、インタフェースが持続性エンジン リポジトリパターン - なぜInterfacesが必要なのか?

を交換し

  • この

    • 使用TDD方式のために使用されていると言い、このポイントを得た。しかし、私はどのようにインターフェースが意志を理解することはできませんよこの時点までに有用であるReplace persistance engine。 は、私は、どのようにインターフェースが絵に来る

      public class EmployeeRepository 
      { 
          public employee[] GetAll() 
          { 
          //here I'll return from dbContext or ObjectContex class 
          } 
      } 
      

      EmployeeRepositoryための(ジェネリックなし)基本的なリポジトリを作成しています考えることができますか?

      私はアップキャスティングを使用する理由をインターフェイスを作成したとしますか?例えば、

      IEmployee emp = new EmployeeRepository() ; 
      vs 
      EmployeeRepository emp = new EmployeeRepository(); 
      

      私はリポジトリパターンに関して正確に、また他の有用性について説明してください。

  • 答えて

    69

    どのようにインターフェイスに画像が表示されますか?

    このよう

    public interface IEmployeeRepository 
    { 
        Employee[] GetAll(); 
    } 
    

    、あなたが好きなように、あなたは、できるだけ多くの実装を持つことができます:

    public class EmployeeRepositoryEF: IEmployeeRepository 
    { 
        public Employee[] GetAll() 
        { 
         //here you will return employees after querying your EF DbContext 
        } 
    } 
    
    public class EmployeeRepositoryXML: IEmployeeRepository 
    { 
        public Employee[] GetAll() 
        { 
         //here you will return employees after querying an XML file 
        } 
    } 
    
    public class EmployeeRepositoryWCF: IEmployeeRepository 
    { 
        public Employee[] GetAll() 
        { 
         //here you will return employees after querying some remote WCF service 
        } 
    } 
    
    and so on ... you could have as many implementation as you like 
    

    をあなたはそれが我々がリポジトリを実装する方法は本当に重要ではありません見ることができるように。重要なことは、すべてのリポジトリと実装が定義された契約(インタフェース)を尊重し、すべてが従業員のリストを返すメソッドGetAllを所有することです。

    このインターフェイスを使用するコントローラがあります。

    public class EmployeesController: Controller 
    { 
        private readonly IEmployeeRepository _repository; 
        public EmployeesController(IEmployeeRepository repository) 
        { 
         _repository = repository; 
        } 
    
        public ActionResult Index() 
        { 
         var employees = _repository.GetAll(); 
         return View(employees); 
        } 
    } 
    

    コントローラがもはやリポジトリの特定の実装に依存しなくなった方法を参照してください。それが知る必要があるのは、この実装が契約を尊重することだけです。これで、必要な実装を使用するように、お気に入りの依存性注入フレームワークを設定するだけです。ここで

    は、これはNinjectをどのように行われるかの例です:

    1. あなたは、単に単一のコード行でEFの実装を使用することを決定し、生成~/App_Start/NinjectWebCommon.csコードでNinject.MVC3 NuGet
    2. をインストールします。

      private static void RegisterServices(IKernel kernel) 
      { 
          kernel.Bind<IEmployeeRepository>().To<EmployeeRepositoryEF>(); 
      }   
      

    あなたは、もはや任意の手動インスタンス化を行う必要がある。この方法それらのリポジトリクラスとupcastingか何かについての心配。それは、あなたのためにそれらを管理し、コントローラのコンストラクタに定義された実装を注入する世話をする依存性注入フレームワークです。

    この設定を変更するだけで、コントローラ内の1行のコードに触れることなくデータアクセス技術を切り替えることができます。それは単体での単体テストもまた有効です。あなたのコントローラコードがリポジトリに弱く結びついているので(私たちが紹介したインターフェイスのおかげで)、単体テストでやる必要があるのはリポジトリにモックの実装を提供して、その動作を定義できるようにすることだけです。これにより、データベースや他のものに依存することなく、インデックスコントローラの動作をユニットテストすることができます。完全な隔離。

    また、ASP.NET MVCのTDDとDIに関するfollowing articlesをチェックアウトすることをお勧めします。

    +1

    wonderfull答え、それぞれの説明は価値があります。私はそれがどのように働くのかを知っています。私のポイントが15歳以下であるので、私はこの答えを受け入れることができません。 – Meson

    +0

    その記事..ありがとう、私の依存性注入フレームワークで 'EmployeeRepositoryEF'を設定すると、私のコントローラはこの' EmployeeRepositoryEF'を消費しますが、もし私が同じコントローラで2つの実装を消費したいのであればどうしますか?非常に残念です.. – Meson

    +2

    例Iのプロバイダでは、コントローラはコンストラクタに 'IEmployeeRepository'インスタンスが必要です。単一の実装のみが渡されます。一方、インターフェイスの別の実装が必要な別のコントローラを使用することもできます。それは完全に可能です。 ControllerBのImplementationAとControllerBのImplementationBを注入するように、DIフレームワークを設定するだけです。構文はもちろん、さまざまなDIフレームワークによって異なります。 –

    14

    あなたはインターフェイスとしてリポジトリを公開します:

    public class EmployeeRepository : IEmployeeRepository 
    { 
        public List<Employee> GetAll() 
        { 
         // Return from db. 
        } 
    } 
    

    または:

    public interface IEmployeeRepository 
    { 
        List<Employee> GetAll(); 
    } 
    

    これは、あなたがそのようなデフォルトの一つとして、多くの異なるの実装インタフェースのを持つことができるようになりますテスト1:

    public class TestEmployeeRepository : IEmployeeRepository 
    { 
        public List<Employee> GetAll() 
        { 
         // Stub some dummy data. 
        } 
    } 
    

    コードリポジトリを消費すると、インターフェイスを使用することにのみ関心がある:

    IEmployeeRepository myRepo = MyRepositoryFactory.Get<IEmployeeRepository>(); 
    

    秘密のソースは、工場、又はNinject、または城として使用可能なタイプ(依存性注入フレームワークにインターフェイスを解決することにより、別のメカニズムでありますウィンザーはこの役割を果たします)。

    ポイントが消費するコードが実装、(インターフェース)のみ契約を気にしない、です。これにより、テスト目的の実装を簡単にスワップアウトして、疎結合を促進することができます。

    明確にするために、インターフェイスとリポジトリパターンの使用の間には具体的な関係はなく、単にそれを利用できる別のパターンです。

    +0

    あなたに感謝してありがとうございます。もう1つ質問します。なぜ、IEmployee emp = new EmployeeRepository(); 'vs' EmployeeRepository emp = new EmployeeRepository(); '?? – Meson

    関連する問題