2009-11-25 231 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