Как я могу заставить Ninject 2 использовать конструктор без параметров для LINQ to SQL DataContext?

Я начал использовать Ninject 2 (загруженный из Github вчера, включая проект расширения MVC), с проектом, основанным на следующих технологиях:

  • .Net 3.5 Sp1
  • ASP.NET MVC 1.0
  • LINQ to SQL

Ничего магического здесь. У меня есть несколько интерфейсов репозитория (называемых IEntityRepository), которые реализованы с использованием LINQ to SQL в коде времени выполнения (и использование хэш-таблицы в коде unit test). Каждому из этих репозиториев нужен экземпляр DataContext от LINQ to SQL, чтобы поговорить с базой данных, так что это параметр конструктора в конкретных группах репозитория. Связывание настраивается следующим образом:

Kernel.Bind<MyDataContext>().ToSelf().InRequestScope();

Причиной этого является то, что я хочу иметь возможность обмениваться сущностями между разными репозиториями, если мне понадобится больше их, и с помощью LINQ to SQL datacontext единицы философии работы, мне кажется, имеет смысл создайте по одному в HttpRequest.

Я обычно использую конструктор без параметров для MyDataContext - я не вижу этого как риск, потому что он используется для внутреннего проекта в тестовой системе, поэтому "встроенная" строка соединения в datacontext безвредна. Однако, поскольку Ninject 2 является "жадным" и хочет, чтобы конструктор с параметрами MOST, и я не могу по-настоящему вставить параметр [Inject] в сгенерированный код каким-либо значимым образом, я получаю сообщение об ошибке, когда Ninject пытается создать один из моих контроллеры (для которых нужен репозиторий, для которого требуется datacontext).

Я заметил упоминание IConstructorScorer и возможность сделать "инвертированный", который всегда будет использовать конструктор с параметрами LEAST, но опять же, это изменит работу инъекций для всего остального - поведение по умолчанию возможно, что я хочу для всего, кроме datacontext.

Итак - есть ли хороший, чистый способ указать, что эта привязка (и только эта привязка) должна использовать определенный конструктор? Можем ли мы сделать то же самое с провайдерами, что и в Ninject 1, и, возможно, поставляем собственный "factory"? Или я должен просто сдаться и попытаться передать параметры в datacontext, которые имеют смысл?

Ответ 1

Выяснил это - это довольно легко сделать, привязываясь к провайдеру;

Kernel.Bind<MyDataContext>().ToProvider<ContextProvider>().InRequestScope();

Теперь Ninject вызовет мой ContextProvider всякий раз, когда ему нужно создать один из этих досадных объектов DataContext. Это выглядит класс моего провайдера:

public class ContextProvider : IProvider
{
    #region IProvider Members

    public object Create(IContext context)
    {
        return new MyDataContext();
    }

    public Type Type
    {
        get { throw new NotImplementedException(); }
    }

    #endregion
}

Кажется, я сошел с рук - он отлично работает.:)

Ответ 2

Я предполагаю, что вы также можете использовать привязку ToMethod, чтобы избежать реализации настраиваемого поставщика, что я использую это:

Kernel.Bind<MyDataConext>().ToMethod(c => new MyDataContext())