ASP.NET Конструктор проверки MVC3 Fluent выполняется несколько раз для каждого запроса

#asp.net-mvc-3 #ninject #fluentvalidation

#asp.net-mvc-3 #ninject #fluentvalidation

Вопрос:

У меня есть ASP.NET Настройка веб-сайта MVC3 с использованием fluent validation и ninject. Код проверки работает. Тем не менее, я установил точку останова в конструкторе класса проверки, и я заметил, что когда я запрашиваю свое представление, которое использует проверку, конструктор попадает несколько раз. Основываясь на очень простом тестировании, кажется, что количество попаданий в конструктор равно количеству свойств, существующих в объекте. Кто-нибудь еще сталкивался с чем-то подобным? Или кто-нибудь может рассказать больше о том, как этот тип проверки работает за кулисами? -Спасибо

Вот конструктор…

 public class PersonValidator : AbstractValidator<Person> {
    public PersonValidator() {
        RuleFor(x => x.Id).NotNull();
        RuleFor(x => x.Name).Length(0, 10);
        RuleFor(x => x.Email).EmailAddress();
        RuleFor(x => x.Age).InclusiveBetween(18, 60);
    }
}
  

Вот библиотеки / ресурсы, которые я использую (я только что получил пакеты NuGet и настроил все на основе информации из двух ссылок ниже):

http://fluentvalidation.codeplex.com/wikipage?title=mvc https://github.com/ninject/ninject.web.mvc.fluentvalidation

Комментарии:

1. Интересный вопрос, знаете ли вы, что именно происходит при вызове (x => x.Id )? Я все еще новичок в выражениях LINQ, но я предполагаю, что это может иметь какое-то отношение к вашей проблеме

2. @CodeRush RuleFor(x => x.Id) означает создать правило для Id свойства Person x . @Zoran как вы настраиваете средство проверки?

3. Я знаком с Linq, и я также сначала использую fluent api с кодом EF. @shuniar — я добавил ссылки на веб-сайты, которые я использовал для настройки своего сайта. Я не могу выполнить все шаги, но я могу сказать, что я заставил проверку работать, выполнив шаги. Я просто хотел бы знать, почему этот код попадает так много раз. Меня это немного беспокоит. 🙂

Ответ №1:

Я выяснил, как предотвратить эту проблему. Несмотря на то, что это решает мою проблему, я хотел бы получить информацию от других о том, есть ли какие-либо последствия при этом?

Итак, по второй ссылке вы увидите инструкции о том, как настроить Ninject.

На втором шаге вам необходимо применить метод расширения «InRequestScope ()«. Тогда конструктор будет выполняться только один раз для каждого http-запроса, который использует ваш валидатор. Это, очевидно, означает, что для каждого http-запроса создается только один экземпляр объекта validator, что имеет смысл для меня. Я не знаю, есть ли какие-либо последствия для использования этого решения?

 Bind(match.InterfaceType).To(match.ValidatorType).InRequestScope();
  

Ответ №2:

Восстановление этого потока.

У меня была такая же проблема с SimpleInjector. Моим решением было включить время жизни.Область действия в регистре сбора.

 private static void WarmUpMediatrAndFluentValidation(this Container container)
    {
        var allAssemblies = GetAssemblies();

        container.RegisterSingleton<IMediator, Mediator>();
        container.Register(typeof(IRequestHandler<,>), allAssemblies);

        RegisterHandlers(container, typeof(INotificationHandler<>), allAssemblies);
        RegisterHandlers(container, typeof(IRequestExceptionAction<,>), allAssemblies);
        RegisterHandlers(container, typeof(IRequestExceptionHandler<,,>), allAssemblies);

        //Pipeline
        container.Collection.Register(typeof(IPipelineBehavior<,>), new[]
        {
            typeof(RequestExceptionProcessorBehavior<,>),
            typeof(RequestExceptionActionProcessorBehavior<,>),
            typeof(RequestPreProcessorBehavior<,>),
            typeof(RequestPostProcessorBehavior<,>),
            typeof(PipelineBehavior<,>)
        });
        
        container.Collection.Register(typeof(IRequestPreProcessor<>), new[] {typeof(EmptyRequestPreProcessor<>)});
        container.Collection.Register(typeof(IRequestPostProcessor<,>), new[] {typeof(EmptyRequestPostProcessor<,>)});

        container.Register(() => new ServiceFactory(container.GetInstance), Lifestyle.Singleton);

        container.Collection.Register(typeof(IValidator<>), allAssemblies, Lifestyle.Scoped);
    }
  

контейнер.Коллекция.Register(typeof(IValidator<>), Все сборки, стиль жизни.Область действия); <- Workers отлично подходит для меня, вызывая только один раз за запрос.