Как я могу заставить 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())