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接口或类似的东西。您不希望对 20Bind个存储库进行 20 次调用 - 您需要比这更高级别的抽象。

我建议最好的解决方案是您应该在构造函数中要求 anIDataContext或 anIDataContextFactory并让其担心。

于 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将连接字符串作为参数传递给其构造函数来实现。然后将 绑定DataContextDataContextProvider.

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 回答