20

SharpRepositoryをNinjectと一緒に使用したいのですが、リポジトリ間で Entity Framework DbContext を共有するように Ninject を構成する方法がわかりません。

Entity Framework バージョン 5 と Ninject バージョン 3 を使用しています。

現在Ef5Repository、ソースコードで使用していますが、に置き換えたいですConfigurationBasedRepositoryDbContextしかし、EFをリポジトリに渡す (または注入する) 方法がわかりません。

例 (現在の状態):

using SharpRepository.Repository;

public interface IProductRepository : IRepository<Product>
{
}

using SharpRepository.Ef5Repository;
using System.Data.Entity;

// TODO Tightly coupled to Ef5Repository.
public class ProductRepository : Ef5Repository<Product>, IProductRepository
{
    // TODO The DbContext has to be injected manually.
    public ProductRepository(DbContext context) : base(context)
    {
    }

    // [...]
}

ゴール:

using SharpRepository.Repository;

public interface IProductRepository : IRepository<Product>
{
}

public class ProductRepository : ConfigurationBasedRepository<Product, int>, IProductRepository
{
    // [...]
}

SharpRepository: Getting StartedSharpRepository: Configurationの 2 つのブログ投稿を既に読みましたが、どちらも役に立ちません。

  1. 使用される DIC は、Ninject ではなく StructureMap です。
  2. ソース コードの例は不完全です (宣言されていない変数の使用など)。

だから私の質問:誰かが上記の目標を達成するためのソースコードの例のハウツーを提供してもらえますか(DbContext拡張するすべてのリポジトリ間で1つのEntity Frameworkインスタンスを共有しますConfigurationBasedRepository)

4

2 に答える 2

16

まず、SharpRepository.Ioc.Ninject NuGet パッケージをインストールする必要があります。Ninject を接続して汎用リポジトリのロードを処理し、SharpRepository が使用する依存関係リゾルバーを設定するための拡張メソッドがここにあります。

Ninject バインディング ルール (kernel.Bind<> へのすべての呼び出し) を設定する場合は常に、以下を追加する必要があります。

kernel.BindSharpRepository();

次に、Global.asax、または App_Start コード、または Bootstrapper ロジック (アプリケーションのスタートアップ コードを呼び出す場所) で、次を追加する必要があります。

// kernel is the specific kernel that you are setting up all the binding for
RepositoryDependencyResolver.SetDependencyResolver(new NinjectDependencyResolver(kernel));

これにより、新しい DbContext を取得するときに、この Ninject カーネルを使用するように SharpRepository に指示されます。

最後に、DbContext 自体のバインディングのルールを設定します。Web アプリケーションを使用している場合は、DbContext のスコープをリクエストごとに設定する必要があります。私は個人的に Ninject を使用していませんが、InRequestScopeを使用するためのこのリファレンスを見つけました。あなたのコードは次のようになると思います:

kernel.Bind<DbContext>().To<MyCustomEfContext>().InRequestScope().WithConstructorArgument("connectionString", ConfigurationManager.ConnectionStrings["MyCustomEfContext"].ConnectionString);

ほとんどの人はこの次の部分を必要としませんが、CustomEfContext にカスタム ロジックがある場合 (たとえば、SaveChanges() への呼び出しをログに記録するためのオーバーライドがあります)、構成ファイルでカスタム コンテキスト タイプを定義する必要があります。そのようです:

<repositories>
  <repository name="ef5Repository" connectionString="CustomEfContext" cachingStrategy="standardCachingStrategy" dbContextType="My.Data.CustomEfContext, My.Data" factory="SharpRepository.Ef5Repository.Ef5ConfigRepositoryFactory, SharpRepository.Ef5Repository" />
</repositories>

dbContextType は、完全な型の名前空間構文を使用して、使用しているカスタム DbContext の型を定義します。これを行う場合は、.Bind<DbContext>() を .Bind<CustomEfContext>() に変更して、カスタム コンテキストで Ninject を Bind に設定する必要があります。しかし、私が通常言ったように、問題なく DbContext を直接使用できます。

于 2013-04-23T16:15:30.320 に答える
6

まず、Jeff T の回答で提供されたソリューションが機能します。

ASP.NET MVC 4 + EF 5 プロジェクトでNinjectを機能させるために行った手順をまとめます。次の例では、特定のリポジトリパターンがSharpRepositoryを介して実装されていることに注意してください。


必要なソフトウェア

  1. Ninjectと「Ninject.MVC3」(「Ninject.Web.Common」もインストール) を NuGet 経由でインストールします
  2. NuGetを使用して、 SharpRepository、「EF5 用の SharpRepository」、および「Ninject IOC を使用した SharpRepository」をインストールします。

リポジトリ層を定義する

  1. DbContext 派生クラスを作成しますDomain.EfContext。それは

    「コンテキストを操作するための推奨される方法」。

    • 必要なすべてDbSet<T>をパブリック プロパティとして宣言します。public DbSet<Product> Products { get; set; }
    • class で次の 2 つのコンストラクターを宣言しますDomain.EfContext

      public EfContext() : base() {}
      public EfContext(string connectionName) : base(connectionName) {}
      

  2. Specific Repositoryのインターフェースを定義します。例:

    // TODO By extending IRepository, the interface implements default Create-Read-Update-Delete (CRUD) logic.
    // We can use "traits" to make the repository more "specific", e.g. via extending "ICanInsert".
    // https://github.com/SharpRepository/SharpRepository/blob/master/SharpRepository.Samples/HowToUseTraits.cs
    public interface IProjectRepository : IRepository<Project>
    {
        // TODO Add domain specific logic here.
    }
    
  3. 特定のリポジトリを実装し、から継承するクラスを定義しますSharpRepository.Repository.ConfigurationBasedRepository<T, TKey>。例:

    public class ProductRepository : ConfigurationBasedRepository<Product, int>, IProductRepository
    {
        // TODO Implement domain specific logic here.
    }
    

コンシューマー層を定義する

  1. コントローラーを作成しますControllers.ProductController

    public class ProductController : Controller
    {
        private IProductRepository Repository { get; private set; }
    
        // TODO Will be used by the DiC.
        public ProductController(IProductRepository repository)
        {
            this.Repository = repository;
        }
    }
    

依存性注入コンテナー (DiC) Ninject を介して依存性注入 (DI) をセットアップする

このファイルApp_Start/NinjectWebCommon.csは Ninject.Web.Common によって自動的に作成され、モジュールをロードしRegisterServices(IKernel kernel) : voidてクラスのメソッドにサービスを登録できますNinjectWebCommon。この例のメソッドの完全なソース コードは次のとおりです。

    private static void RegisterServices(IKernel kernel)
    {
        kernel.BindSharpRepository();
        RepositoryDependencyResolver.SetDependencyResolver(
            new NinjectDependencyResolver(kernel)
        );

        string connectionString = ConfigurationManager.ConnectionStrings["EfContext"].ConnectionString;
        kernel.Bind<DbContext>()
            .To<EfContext>()
            .InRequestScope()
            .WithConstructorArgument("connectionString", connectionString);

        kernel.Bind<IProductRepository>().To<ProductRepository>();
    }

sharpRepositoryで次のセクションを定義しますWeb.config

    <sharpRepository>
        <repositories default="ef5Repository">
            <repository name="ef5Repository"
                connectionString="EfContext"
                cachingStrategy="standardCachingStrategy"
                dbContextType="Domain.EfContext, Domain"
                factory="SharpRepository.Ef5Repository.Ef5ConfigRepositoryFactory, SharpRepository.Ef5Repository"
            />
        </repositories>
    </sharpRepository>

さらにconnectionStrings、例を完成させるためのセクション (私は SQL Server LocalDB を使用しています)。

    <connectionStrings>
        <add name="EfContext" providerName="System.Data.SqlClient" connectionString="Data Source=(localdb)\v11.0;Initial Catalog=Domain;Integrated Security=True" />
    </connectionStrings>

この結論が、ASP.NET MVC 4 と Entity Framework 5 および SharpRepository を一緒に起動して実行するために、他の人に役立つことを願っています!

不要な手順を 1 つ以上行った場合、または例で説明されているアーキテクチャを改善する可能性がある場合は、返信を残してください。

ところで、それを機能させるにdbContextType、セクションに属性を追加するrepository必要がありました(Jeff Tの回答とは対照的です)。


編集 (2013-08-28):不要な手順を削除しました (最新バージョンの SharpRepository では必要ありません)。

于 2013-04-25T09:41:01.250 に答える