В чем разница между "областью", "контекстом" и т. д. в Ninject?

могут ли понятия Ninject объем, контекст, именованные привязкиблок активации!--3-->?) быть разделенными и четко объясненными на концептуальном уровне?

в качестве примера у меня есть служба, которая загружает записи данных из базы данных и для каждой записи создает "рабочего" через расширение фабрики Ninject. И служба, и отдельные работники используют контекст объекта Entity Framework для взаимодействия с базой данных. ObjectContext вводится через конструктор для обоих (а также для других общих зависимостей). В настоящее время он однопоточный, но в конечном итоге рабочие должны работать в своих собственных потоках параллельно, и поэтому им понадобится собственный экземпляр ObjectContext и явный жизненный цикл запуска/удаления. Экземпляр ObjectContext должен быть общим для продолжительности "единицы работы" работника (и поэтому не является переходным, поскольку он вводится в несколько репозиториев, используемых работник.) Я застрял, пытаясь получить эту функциональность.

Я наивно хотел чего-то подобного (используя именованная область и контексте сохранения расширения):

Bind<MyDbContext>().ToSelf();
Bind<MyService>().ToSelf();

Bind<IWorkerFactory>().ToFactory().InThreadScope();  // scope prob not necessary

Bind<MyWorker().ToSelf().DefinesNamedScope("workerScopeName");
Bind<MyDbContext>().ToSelf().InNamedScope("workerScopeName");

это очевидно (по крайней мере, очевидно для пользователей Ninject) приводит к "более чем одной соответствующей привязке..."ошибка из-за MyDbContext. Прочитав гораздо больше, я теперь думаю я, вероятно, должен использовать именованные привязки для работника и это ObjectContext. Я!--22-->думаю мне все еще нужна область, чтобы я мог явно распоряжаться ObjectContext, когда рабочий закончил (и имеет метод dispose из обработки области ninject).

в любом случае, я все еще в основном догадываюсь, и я публикую этот вопрос в надежде, что кто-то может прояснить эти понятия в Ninject.

1 ответов


контекст: метаинформация для текущего разрешения. Он указывает, куда в дереве объектов будет введен текущий разрешенный объект. (например, в настоящее время разрешенный объект будет введен в конструктор класса A, который вводится в класс B,....) Его можно использовать, например, чтобы решить, применяется ли привязка в текущем контексте, используя один из When перегрузок. Он передается и многим другим обратным вызовам синтаксиса fluent (например, InScope, Онактивация, ....)

объем: определяет жизненный цикл объекта и при повторном использовании существующего экземпляра существует множество предопределенных областей, а также общая область, которая может указать область из текущего контекста (InScope(ctx => ...)

Названы Обязательными: метаинформация о привязке. Может использоваться в сочетании с контекстом. Например. Привязка применяется только тогда, когда в текущем контексте любая из родительских Привязок имеет некоторые имя.

Блок Активации: (по состоянию на Ninject 2.x-3.x, это, вероятно, изменится в будущих версиях). В блоке активации каждая привязка изменяется, чтобы иметь блок активации в качестве области действия. Это означает, что область, указанная в привязке, будет проигнорирована. Для разрешения одного блока активации будет создан ровно один экземпляр.

Я лично не использовал бы эту функцию, потому что она имеет недостатки, игнорируя все виды других областей, таких как InSingletonScope. Лучше использовать области, заданные Ninject.Увеличение.NamedScope.

относительно вашего примера: так как у вас есть два MyDbContext привязки вам нужно будет добавить к ним условия. например,WhenAnyAncestorNamed. Или вы можете использовать другую область, например InCallScope() только с одной привязкой.