Ninject и строки подключения - PullRequest
8 голосов
/ 26 ноября 2009

Я очень новичок в Ninject и пробую Ninject 2 с MVC и Linq. У меня есть класс 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 ]

15 голосов
/ 26 ноября 2009

Вы можете установить его в своем переплете


_kernel.Bind<IProductRepository>()
       .To<SqlProductRepository>()
       .WithConstructorArgument("connectionString",yourConnectionString );
5 голосов
/ 26 ноября 2009

Вы делаете:

new DataContext(connectionString)

в вашем коде - это самое новое и связующее с классами, которые вы пытаетесь вытолкнуть из своего кода с помощью контейнера DI. По крайней мере, рассмотрите возможность добавления интерфейса IConnectionStringSelector или что-то в этом роде. Вы не хотите иметь 20 Bind вызовов для 20 репозиториев - вам нужна абстракция более высокого уровня, чем эта.

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

2 голосов
/ 26 ноября 2009

Вы можете указать строку подключения в качестве аргумента конструктора при привязке 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 голосов
/ 09 декабря 2011

Пожалуйста, обратитесь к снимку кода ниже:

    //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

...