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

Autofac - InstancePerHttpRequest vs InstancePerLifetimeScope

Каковы различия между двумя областями?

Я создаю Module на каждом уровне (репозиторий, сервис, приложение MVC), но для того, чтобы InstancePerHttpRequest вам нужна сборка Autofac.Mvc.

Какую область действия я должен использовать на моем уровне репозитория и службы?

4b9b3361

Ответ 1

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

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

Единственное реальное различие возникает, если у вас есть служба, зарегистрированная в InstancePerHttpRequest, и вы запрашиваете одну из этих служб из другой службы, которая зарегистрирована как SingleInstance. В этом случае:

  • Компонент SingleInstance живет в области root
  • Компонент InstancePerHttpRequest живет в области под названием "AutofacWebRequest", которая является дочерней частью корневой области.

Autofac не разрешает разрешение от дочерних областей - поэтому по существу служба SingleInstance не может найти службу InstancePerHttpRequest.

Однако, если в этом случае вы использовали InstancePerLifetimeScope (вместо InstancePerHttpRequest), тогда ваши службы разрешали бы просто отлично.

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

Одно из распространенных заблуждений заключается в том, что регистрация вашего компонента с помощью экземпляра InstancePerLifetimeScope в приложении WebAPI означает, что ваш компонент находится в области веб-запроса, то есть "Lifetime" относится к "времени жизни веб-запроса". Как вы можете видеть здесь, это неверно.

Время жизни вашего компонента определяется областью, в которой оно было разрешено.

Так как SingletonResolvable разрешает свой токен из области корня, этот токен-экземпляр живет в корневой области, а не в области веб-запроса. Ive сказал это раньше, но я говорю это еще раз: этот токен будет жить до тех пор, пока не будет удалено все приложение (например, рабочий процесс IIS будет переработан). Все, что запрашивает ScopeToken из области корня, будет дано указание на этот токен.

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

Ответ 2

Единственное место в вашем приложении, которое полностью способно принять решение о времени жизни объекта, находится в корне композиции.

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

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

  • Он вводит зависимость от Autofac, которую я не хочу, кроме как в моем составе root
  • Это говорит о том, что модуль знает, как управлять жизненным циклом, что обычно не так. Если это так, почему бы не предоставить factory или другие классы, которые обеспечивают управление жизненным циклом?

Вместо этого (и в проектах, достаточно больших, чтобы гарантировать), я создаю модули на корневом уровне композиции, так как на этом уровне у меня есть явные знания о том, как они должны быть связаны друг с другом. Иногда я создаю сборку Ioc, которая содержит модули и которая действует как корень композиции по умолчанию, но это часто переопределяется в "реальном" корневом составе (например, приложение консоли или MVC, которое тянет в Ioc сборка).

Ответ 3

В Autofac за всю жизнь область - это общий способ создания пользовательских областей с использованием вложенных времен жизни.

Использование InstancePerLifetimeScope дает вам область запроса, которая добавляет время жизни компонента для одного запроса и внутренне использует InstancePerLifetimeScrope для этого компонента.

Используйте InstancePerLifetimeScope везде, где это необходимо, или если проблема связана с записью на Autofac.Integration.Mvc на уровне вашего сервиса - создайте вложенные области вручную в каждом начале запроса и используйте InstancePerLifetimeScope.