2009-11-25 6 views
8

Я очень новичок в Ninject и пытаюсь Ninject 2 с MVC и Linq. У меня есть класс SqlProductRepository, и все, что я хочу знать, это лучший способ передать connectionstring в конструкторе, если я вставляю объект Repository в контроллер.Ninject And Connection Strings

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 Bind вызовов для 20 репозиториев - вам нужна абстракция более высокого уровня, чем это.

Я бы предложил лучшее решение, что вместо этого вы должны требовать либо IDataContext, либо IDataContextFactory в конструкторе, и позволить этому беспокоиться об этом.

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