Вопрос
Я расследую использование Autofac в нашем веб-приложении, поскольку ранее использовал Castle Windsor в прошлом.
Что мне действительно нравится в Autofac, так это возможность выражать построение динамических компонентов с помощью выражений lamda, в отличие от создания DependancyResolvers и т.д.в Виндзоре.
Один из сценариев-это то, что я хочу, чтобы определенный компонент должен быть зарегистрирован в ASP.NET сессии уровне области.С Windsor я бы создал / отправил новый LifestyleManager, однако с Autofac я придумал это:
//Register SessionContext at HTTP Session Level
builder.Register(c =>
{
HttpContext current = HttpContext.Current;
//HttpContext handes delivering the correct session
Pelagon.Violet.Core.Interfaces.SessionContext instance = current.Session["SessionContext"] as Pelagon.Violet.Core.Interfaces.SessionContext;
if (instance == null)
{
instance = c.Resolve<Pelagon.Violet.Core.Interfaces.SessionContext>();
current.Session["SessionContext"] = instance;
}
return instance;
})
.FactoryScoped();
Который в какой-то момент я, возможно, смог бы превратить в метод расширения.Я принимаю, что эта реализация сработает, если HttpContext.Current.Сеанс равен нулю, поскольку он должен использоваться только в веб-приложении.
Вопрос в том,:
Какова наилучшая практика для такой регистрации в Autofac.Я видел много упоминаний об использовании вложенных контейнеров и т.д.но конкретных примеров нет, и я очень хочу понять, что может быть не так с описанным выше подходом (единственное, что я могу придумать, это автоматическое удаление материала).
Спасибо.
Решение
Это выглядит прекрасно.
Пометка компонента 'ExternallyOwned()' гарантирует, что Autofac не вызовет Dispose()
на нем.
Единственные ошибки здесь заключаются в том, что ваш компонент с сессионной областью может разрешать собственные зависимости через текущий контейнер и, таким образом, содержать ссылки на объекты, которые могут принадлежать текущему запросу (например.) Однако это должно быть легко обнаружить при тестировании.