Можно ли вернуть null в некоторых ситуациях для зарегистрированных типов в Autofac? - PullRequest
2 голосов
/ 12 июля 2011

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

builder.Register( c => c.Resolve<HttpContextBase>().CurrentHandler as ITemplatePage
                ).InstancePerHttpRequest();

В этом примере будет возвращено значение NULL, если текущий обработчик (например, страница aspx, которую я посещаю) не имеет типа ITemplatePage, и Autofac сгенерирует исключение DependencyResolutionException, даже еслиЯ использую альтернативу ResolveOptional следующим образом:

container.ResolveOptional<ITemplatePage>(); 

Можно ли как-то обойти это и получить поведение, при котором Autofac возвращает null вместо того, чтобы выдавать исключение?

Я работалвокруг этого, добавив IsNull-proerty к ITemplatePage и всегда создавая его, например:

builder.Register( c => 
                  c.Resolve<HttpContextBase>().CurrentHandler as ITemplatePage
                  ?? new TemplatePage(true)
                 ).As<ITemplatePage>().InstancePerHttpRequest();

, а затем я могу работать с ним следующим образом:

var templatePage = container.Resolve<ITemplatePage>();  
if(!templatePage.IsNull){
   // Do stuff
}

Но я делаюне думаю, что это оптимальное решение моей проблемы.

Редактировать: поймать ошибку не вариант, так как я использую ITemplatePage в конструкторах других типов, которые я разрешаю, и так как я использую конструктор для разрешения этих типовЯ хочу, чтобы они возвращали экземпляр, созданный с помощью конструктора без параметра ITemplatePage, а не cсыпь.

1 Ответ

4 голосов
/ 13 июля 2011

Лучший способ сделать это - условно зарегистрировать службу в начале веб-запроса, например, (Псевдокод):

void Application_BeginRequest()
{
    var tp = HttpContext.CurrentHandler as ITemplatePage;
    if (tp != null)
    {
        var updater = new ContainerBuilder();
        updater.RegisterInstance(tp);
        updater.Update(ContainerProvider.RequestLifetime.ComponentRegistry);
    }
}

Таким образом, вы можете просто сделать ITemplatePage необязательным параметром конструктора компонентов, которые могут его использовать (ITemplatePage tp = null) или использовать внедрение свойства / ResolveOptional().

Обратите внимание, что в этих типах отложенных регистраций в Autofac 2.5 произошли некоторые улучшения надежности, поэтому я рекомендую обновить их перед использованием.

...