1

Я пытаюсь настроить поставщика проверки подлинности модели, используя FluentValidation. Все работает, пока я не попытаюсь внедрить менеджера бизнес-уровня в конструктор валидатора, чтобы запустить некоторую бизнес-логику.Autofac scoping issue

public class Repository : IRepository 
{ 
    public Repository(IDbConnection) 
    { 
    } 
} 

public class Manager : IManager 
{ 
    public Manager(IRepository) 
    { 
    } 
} 

public AutofacValidatorFactory : ValidatorFactoryBase 
{ 
} 

public MyModelValidator : AbstractValidator<MyModel> 
{ 
    public MyModelValidator(IManager) { } 
} 

Я проволокой все вверх так:

builder.Register(c => new SqlConnection(ConfigurationManager.ConnectionStrings["MyCS"].ConnectionString)) 
       .As<IDbConnection>().InstancePerApiRequest(); 

builder.RegisterType<Repository>() 
       .As<IRepository>() 
       .InstancePerDependency(); 

builder.RegisterType<Manager>() 
       .As<IManager>() 
       .InstancePerDependency(); 

builder.RegisterType<ValidatorFactory>() 
       .As<IValidatorFactory>() 
       .InstancePerLifetimeScope(); 

     builder.RegisterType<FluentValidation.Mvc.WebApi.FluentValidationModelValidatorProvider>() 
       .As<ModelValidatorProvider>() 
       .InstancePerLifetimeScope(); 

     AssemblyScanner.FindValidatorsInAssembly(assembly) 
         .ForEach(
          result => 
          Builder.RegisterType(result.ValidatorType).As(result.InterfaceType).InstancePerApiRequest()); 

Наконец, я добавить FluentValidator модель Provider так:

// _validatorProvider is injected as per Autofac config above.  
GlobalConfiguration.Configuration.Services.Add(typeof(ModelValidatorProvider), _validatorProvider); 

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

«Нет сфера с согласования тегов„AutofacWebRequest“не видна из сферы, в которой испрашивается экземпляр Как правило, это указывает на то, что компонент зарегистрирован как за HTTP запрос запрашивается компонентом SingleInstance() (или аналогичным сценарием). В рамках веб-интеграции всегда запрашиваются зависимости от DependencyResolver.Current или ILifetimeScopeProvider.RequestLifetime, никогда из самого контейнера. "

Я думаю, что проблема имеет что-то делать с тем, как Диспетчер & Repository сконфигурирован в Autofac, но я не знаю, что я не хватает.

EDIT: эта проблема возникает в проекте веб-API.

+1

Как вы решаете валидатор? Не могли бы вы опубликовать свою фабричную фабрику Validator? –

ответ

2

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

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

Регистрация как SingleInstance означает, что один экземпляр разрешен и сохраняется в корневой области. Использование InstancePerLifetimeScope воссоздает каждый экземпляр для каждой области, из которой он был разрешен, поэтому вы можете получить экземпляр в корневой области и область вашего ребенка. InstancePerMatchingLifetimeScope позволяет зарегистрировать тип, чтобы он был общим для всех дочерних контейнеров этой конкретной ветви дерева. Эти типы никогда не могут существовать или быть доступными ничем в корневой области. InstancePerApiRequest совпадает с InstancePerMatchingLifetimeScope («AutofacWebRequest»).

В вашем приложении каждый запрос будет представлять собой дочернюю область автозапуска. Что-то зарегистрированное в области child (например, ваше IDBConnection) может использовать что-либо еще в той же области (зарегистрированной как InstancePerLifetimeScope) и все в родительской области (зарегистрированной как SingleInstance), однако здесь существует потенциальная проблема. Что-то, зарегистрированное в родительской области (например, как SingleInstance в корневом контейнере), не может получить доступ к чему-либо, зарегистрированному как InstancePerMatchingLifetimeScope, в области дочерних объектов, поскольку родительская область не имеет доступа к экземплярам в дочерних областях.

Это то, что вы, скорее всего, сделали - зарегистрировали что-то как SingleInstance, которое имеет зависимость от того, что зарегистрировано в области соответствия времени жизни.