2009-11-25 233 views
8

我對Ninject很新,我正在嘗試Ninject 2與MVC和Linq。我有一個SqlProductRepository類,我想知道的是,如果我在控制器中注入Repository對象,在構造函數中傳遞connectionstring的最佳方式是什麼。Ninject和連接字符串

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() 
        ); 
    } 
} 

有人可以請指導我對此?

回答

15

你可以將它設置在你的綁定

 

_kernel.Bind<IProductRepository>() 
     .To<SqlProductRepository>() 
     .WithConstructorArgument("connectionString",yourConnectionString); 
5

你這樣做:

new DataContext(connectionString) 
在你的代碼

- 這是非常newing並綁定到你要推類通過使用DI容器將代碼排除在外。至少,考慮添加一個IConnectionStringSelector接口或類似的東西。你不想要20個倉庫的20 Bind - 你想要一個更高層次的抽象。

我建議最好的解決方案是,您應該要求在構造函數中使用IDataContextIDataContextFactory,並讓它擔心它。

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會默認選擇參數最多的構造函數。

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 and Ninject.MVC3 problem