8

私は Ninject を初めて使用し、MVC と Linq で Ninject 2 を試しています。私は SqlProductRepository クラスを持っています。私が知りたいのは、コントローラーに Repository オブジェクトを注入している場合、コンストラクターで接続文字列を渡す最良の方法は何かということだけです。

public class SqlProductRepository:IProductRepository
{
    private Table<Product> productsTable;

    public SqlProductRepository(string connectionString)
    {
      productsTable = (new DataContext(connectionString)).GetTable<Product>();   
    }

    public IQueryable<Product> Products
    {
        get { return productsTable; }
    }
}

これは、リポジトリを挿入する ProductController クラスです。

  public class ProductsController : Controller
{
    private int pageSize = 4;
    public int PageSize { get { return pageSize; } set { pageSize = value; } }  

    IProductRepository _productsRepository;

    [Inject]
    public ProductsController(IProductRepository productRepository)
    {
        _productsRepository = productRepository;
    }

    public ViewResult List(int page)
    {
        return View(_productsRepository.Products
                                       .Skip((page - 1) * pageSize)
                                       .Take(pageSize)
                                       .ToList()
                    );
    }
}

誰かがこれに関して私を案内してもらえますか?

4

4 に答える 4

15

バインディングで設定できます


_kernel.Bind<IProductRepository>()
       .To<SqlProductRepository>()
       .WithConstructorArgument("connectionString",yourConnectionString );
于 2009-11-25T22:03:48.577 に答える
5

あなたはやっている:

new DataContext(connectionString)

コード内-これは、DIコンテナーを使用してコードからプッシュしようとしている、非常に新しく、クラスへのバインドです。少なくとも、IConnectionStringSelectorインターフェースなどを追加することを検討してください。20個のリポジトリに対して20Bind回の呼び出しを行う必要はありません。それよりも、より高いレベルの抽象化が必要です。

最善の解決策は、代わりにコンストラクターでanIDataContextまたはanのいずれかを要求IDataContextFactoryし、それについて心配させることです。

于 2009-11-26T08:59:47.783 に答える
2

SqlProductRepositoryをインターフェイスにバインドするときに、接続文字列をコンストラクター引数として指定IProductRepositoryできます。

public class LinqToSqlModule : NinjectModule
{
    public override void Load()
    {
        Bind<IProductRepository>().To<SqlProductRepository>()
            .WithConstructorArgument(connectionString, "connectionstring");
    }
}

少し異なるアプローチをお勧めします。まずDataContext、カーネルでクラスのバインドを作成する必要がある場合があります。これを行うには、プロバイダー クラスを使用してDataContext、接続文字列を引数としてコンストラクターに渡します。次に、 を にバインドしDataContextますDataContextProvider

public class DataContextProvider : Provider<DataContext>
{
    protected override DataContext CreateInstance(IContext context)
    {
        string connectionString = "connectionstring";
        return new DataContext(connectionString);
    }
}

public class LinqToSqlModule : NinjectModule
{
    public override void Load()
    {
        Bind<DataContext>().ToProvider<DataContextProvider>();
        Bind<IProductRepository>().To<SqlProductRepository>();
    }
}

次に、代わりにオブジェクトSqlProductRepositoryを受け入れるようにクラスのコンストラクターを変更します。DataContext

public class SqlProductRepository : IProductRepository
{
    private readonly DataContext context;

    public ProductRepository(DataContext context)
    {
        this.context = context;
    }

    public IQueryable<Product> Products
    { 
        get { return context.GetTable<Product>(); }
    }
}

ちなみに、コンストラクターをInject属性で装飾する必要はありません。Ninject は、デフォルトで最も多くのパラメーターを持つコンストラクターを選択します。

于 2009-11-26T18:41:29.077 に答える
0

以下のコード スナップを参照してください。

    //Bind the default connection string
    public void BindDataContext()
    {
        ConstructorArgument parameter = new ConstructorArgument("connectionString", "[Config Value]");
        Bind<DataContext>().ToSelf().InRequestScope().WithParameter(parameter);
    }
    //Re-Bind the connection string (in case of multi-tenant architecture)
    public void ReBindDataContext(string cn)
    {
         ConstructorArgument parameter = new ConstructorArgument("connectionString", cn);
         Rebind<DataContext>().ToSelf().InRequestScope().WithParameter(parameter);
    }

詳細については、以下のリンクをご覧ください。

MVC3、Ninject および Ninject.MVC3 の問題

于 2011-12-09T13:52:10.920 に答える