Подтвердить что ты не робот

Конструкторы связывания Ninject с аргументами/Строка подключения Entity Framework

Пожалуйста, простите мое невежество, но я очень новичок в IOC и NinJect. Я искал высокий и низкий для легко понятных решений, но до сих пор они ускользали от меня.

До сих пор у меня есть следующие и все работает как ожидалось:

private class StandardModule : NinjectModule
    {
      public override void Load()
      {
        Bind<ILog>().To<NLogLogger>();    // Use NLog
        Bind<IMyEntityFrameWorkRepository().To<MyEntityFrameWorkRepository>();
      }
    }

MyEntityFrameWorkRepository создает собственный EF DbContext через строку соединения, объявленную в app/web.config:

public class MyDbContext : DbContext
{
   public MyDbContext() : base("MyAppConfig")
   {
   }
   ........
}

ОДНАКО!! Моя цель - это что-то вроде этого. Я понимаю, что этот синтаксис - это "нонсенс" (и я думаю, что, возможно, мне тоже придется использовать MyCb), но я надеюсь, что "псевдокод" передает мое желание:

private class StandardModule : NinjectModule
{
  public override void Load()
  {
    Bind<ILog>().To<NLogLogger>();    // Use NLog

    string mySqlConnectionString = MyApp.GetCommandLineArgument("sqlconn"); // "Data Source=..."
    Bind<IMyEntityFrameWorkRepository().To<MyEntityFrameWorkRepository>(mySqlConnectionString);
  }
}

.................

public class MyDbContext : DbContext
{
   public MyDbContext( string sqlConnectionString) :
      base(sqlConnectionString) // will accept a standard SQL connection string
   {
   }
   ........
}

Я бы по-настоящему оценил некоторые отзывы экспертов IOC/NinJect, так как я уверен, что любой "шаблон" может быть очень полезен в других сценариях.

4b9b3361

Ответ 1

Вы можете использовать метод .WithConstructorArgument() для указания аргументов конструктора. Первым аргументом должно быть имя параметра конструктора.

public class StandardModule : NinjectModule
{
    public override void Load()
    {
        string connectionString = "...";
        Bind<IMyEntityFrameWorkRepository().To<MyEntityFrameWorkRepository>()
            .WithConstructorArgument("sqlConnectionString", connectionString);
    }

}

Ответ 2

Более новые версии Ninject позволяют избавиться от магических строк в определении привязки. Что-то вроде этого:

public class StandardModule : NinjectModule
{
    public override void Load()
    {
        string connectionString = "...";
        Bind<IMyEntityFrameWorkRepository()
            .ToConstructor(_ => new MyEntityFrameWorkRepository(connectionString);
    }
}

Для привязок, включающих общие типы (например, bind ISomeService<T> to SomeService<T> и привязка должна выполняться сразу для всех возможных типов), ToConstructor не может использоваться (требуется новое выражение), поэтому WithConstructorArgument остается самый простой подход. Например:.

Bind(typeof(ISomeService<>))
    .To(typeof(SomeService<>))
    .WithConstructorArgument("someParam", "someValue");