2016-07-07 4 views
0

Контекст: Owin (самообеспечение хост) + WebAPI + UseAutofacMiddleware + UseAutofacWebApiУправление Lifetime Прицелы с Autofac

То, что я пытаюсь сделать, это:

Зарегистрировать ILog экземпляр в контейнере запуска приложения.

Для каждого запроса зарегистрируйте новый экземпляр ILog, обертывающий «корневой» экземпляр, чтобы каждое его промежуточное программное обеспечение и/или службы запроса могли его использовать.

var containerBuilder = new ContainerBuilder(); 
containerBuilder.RegisterInstance(log).As<ILog>(); 
containerBuilder.Register(ctx => { 
    var rootLog = ctx.Resolve<ILog>(); 
    return new PrependStringLog(rootLog, "request: "); 
}).InstancePerRequest(); 

Однако Autofac жалуется на циклическую зависимость, когда Instancing промежуточного слоя, имеющий в своих конструкторах в ILog.

Если я называю «корневой журнал» и разрешаю с заданным именем, все работает так, как ожидалось.

containerBuilder.RegisterInstance(log) 
       .Named("root", typeof(ILog)); 
containerBuilder.Register(ctx => { 
    var rootLog = ctx.ResolveNamed<ILog>("root"); 
    return new PrependStringLog(rootLog, "request: "); 
}).InstancePerRequest(); 

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

ответ

1

Autofac использует последний зарегистрированный сервис при запросе компонента на услугу.

В вашем случае, последняя ILog зарегистрирована является лямбда-выражение:

containerBuilder.Register(ctx => { 
    var rootLog = ctx.Resolve<ILog>(); 
    return new PrependStringLog(rootLog, "request: "); 
}).InstancePerRequest(); 

Этот запрос лямбда-выражение ILog что и Autofac пытается построить: именно поэтому он обнаруживает циклическую зависимость.

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

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

containerBuilder.RegisterInstance(rootLog).As<ILog>(); 
containerBuilder.Register(ctx => { 
    return new PrependStringLog(rootLog, "request: "); 
}).InstancePerRequest(); 
+0

На моем взгляде, имея разные прижизненные прицелы были достаточно, чтобы ослабить механизм разрешения. В конце концов, область запроса по запросу имеет родительскую область, в которой уже имеется вполне допустимый экземпляр ILog, и это будет циклическая зависимость. При этом я понимаю ваши рассуждения, я буду продолжать использовать именованные экземпляры. – Raine

Смежные вопросы