English 中文(简体)
Ninject And Connection Strings
原标题:

I am very new to Ninject and am trying Ninject 2 with MVC and Linq. I have a SqlProductRepository class and all I want to know is what s the best way of passing the connectionstring in the constructor if I am injecting the Repository object in the controller.

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

This is my ProductController class where I am injecting the Repository:

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

Can somebody please guide me regarding this?

问题回答

You can set it up in your binding


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

You re doing:

new DataContext(connectionString)

in your code - this is the very newing and binding to classes you re trying to push out of your code by using a DI container. At the very least, consider adding an IConnectionStringSelector interface or something like that. You dont want to have 20 Bind calls for 20 repositories - you want a higher level abstraction than that.

I d suggest the best solution is that you should be demanding either an IDataContext or an IDataContextFactory in the constructor instead and letting that worry about it.

You could supply the connection string as a constructor argument when binding the SqlProductRepository to the IProductRepository interface.

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

I would suggest a slightly different approach. First of all, you might want to create a binding for the DataContext class in the kernel. You could do so by using a provider class to create your DataContext passing the connection string as an argument to its constructor. Then you bind the DataContext to the 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>();
    }
}

Next modify the constructor of SqlProductRepository class to accept a DataContext object instead.

public class SqlProductRepository : IProductRepository
{
    private readonly DataContext context;

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

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

By the way you don t have to decorate your constructor with the Inject attribute. Ninject will select the constructor with the most parameters by default.

Please refer below code snap:

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

For more information, please visit below link

MVC3, Ninject and Ninject.MVC3 problem





相关问题
WebForms and ASP.NET MVC co-existence

I am trying to make a WebForms project and ASP.NET MVC per this question. One of the things I ve done to make that happen is that I added a namespaces node to the WebForms web.config: <pages ...

Post back complex object from client side

I m using ASP.NET MVC and Entity Framework. I m going to pass a complex entity to the client side and allow the user to modify it, and post it back to the controller. But I don t know how to do that ...

Create an incremental placeholder in NHaml

What I want to reach is a way to add a script and style placeholder in my master. They will include my initial site.css and jquery.js files. Each haml page or partial can then add their own required ...

asp.net mvc automapper parsing

let s say we have something like this public class Person { public string Name {get; set;} public Country Country {get; set;} } public class PersonViewModel { public Person Person {get; ...

structureMap mocks stub help

I have an BLL that does validation on user input then inserts a parent(PorEO) and then inserts children(PorBoxEO). So there are two calls to the same InsertJCDC. One like this=>InsertJCDC(fakePor)...

ASP.NET MVC: How should it work with subversion?

So, I have an asp.net mvc app that is being worked on by multiple developers in differing capacities. This is our first time working on a mvc app and my first time working with .NET. Our app does not ...

System.Web.Mvc.Controller Initialize

i have the following base controller... public class BaseController : Controller { protected override void Initialize(System.Web.Routing.RequestContext requestContext) { if (...

热门标签