1
I Use This!
Activity Not Available

News

Posted over 11 years ago by NanoSbz
Hi, Im developing an application using ASP.NET WebAPI 5.1.0 and Autofac 3.2, both latest releases. Im trying to integrate FluentValidation using Autofac but i can't make it work. Error: No scope with a Tag matching 'AutofacWebRequest' is visible ... [More] from the scope in which the instance was requested. This generally indicates that a component registered as per-HTTP request is being requested by a SingleInstance() component (or a similar scenario.) Under the web integration always request dependencies from the DependencyResolver.Current or ILifetimeScopeProvider.RequestLifetime, never from the container itself. Code: # Global.asax Initialization public class WebApiApplication : System.Web.HttpApplication { protected void Application_Start() { Bootstrapper.Register(); AreaRegistration.RegisterAllAreas(); GlobalConfiguration.Configure(WebApiConfig.Register); FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); RouteConfig.RegisterRoutes(RouteTable.Routes); BundleConfig.RegisterBundles(BundleTable.Bundles); } } # Autofac Configuration public static class Bootstrapper { public static void Register() { var builder = new ContainerBuilder(); builder.RegisterApiControllers(Assembly.GetExecutingAssembly()); builder.RegisterWebApiFilterProvider(GlobalConfiguration.Configuration); builder.RegisterType<DataContext>().As<IDbContext>().InstancePerApiRequest(); builder.RegisterType<UnitOfWork>().As<IUnitOfWork>().InstancePerApiRequest(); builder.RegisterAssemblyTypes(typeof(IService).Assembly).Where(x => x.Name.EndsWith("Service")).AsImplementedInterfaces().InstancePerApiRequest(); builder.RegisterModule<AutofacValidationModule>(); var container = builder.Build(); GlobalConfiguration.Configuration.DependencyResolver = new AutofacWebApiDependencyResolver(container); FluentValidationModelValidatorProvider.Configure(x => x.ValidatorFactory = new AutofacValidatorFactory(container)); DataAnnotationsModelValidatorProvider.AddImplicitRequiredAttributeForValueTypes = false; } } # AutofacValidationModule public class AutofacValidationModule : Module { protected override void Load(ContainerBuilder builder) { AssemblyScanner findValidatorsInAssembly = AssemblyScanner.FindValidatorsInAssembly(typeof(AutofacValidationModule).Assembly); foreach (AssemblyScanner.AssemblyScanResult item in findValidatorsInAssembly) { builder.RegisterType(item.ValidatorType).Keyed<IValidator>(item.InterfaceType).As<IValidator>(); } } } # AutofacValidatorFactory public class AutofacValidatorFactory : ValidatorFactoryBase { private readonly IContainer _Container; public AutofacValidatorFactory(IContainer container) { _Container = container; } public override IValidator CreateInstance(Type validatorType) { return _Container.ResolveOptionalKeyed<IValidator>(validatorType); } } # Sample Model [Validator(typeof(PersonValidator))] public class Person { public int ID { get; set; } public string Name { get; set; } } # Sample Model Validator public class PersonValidator : AbstractValidator<Person> { public PersonValidator(IPersonService service) { //Rules.. } } I think that the following article [http://robdmoore.id.au/blog/2013/03/23/resolving-request-scoped-objects-into-a-singleton-with-autofac/] talks about the same issue but the resolution is for MVC and i could't find a way of making it work in WebAPI. Thanks in advance. [Less]
Posted over 11 years ago by Looooooka
Actually I just wanted to use existing DataAnnotation resource files with Fluent Validation. Had those defined with multiple parameters{0},{1}...and in some cases I used tried to lambda expressions to get the values. Ofcourse this didn't work with ... [More] Fluent Validation. Then I was hoping this param array overload would work, expecting the parameters to be used and the {0},{1} to be replaced by the order entered in the param object array. That doesn't happen. The Length validator only seems to use it's min and max setting when constructing the Message (in both WithLocalizedMessage and WithMessage functions). Luckily for me the only parameter I really needed was the property name...which can be added with the {PropertyName} variable. So my problem is solved. But in case I ever want to achieve to above sample...is it possible? "a","b","c" to be used in the resource file as {0},{1}... or AT LEAST if min and max settings are always passed as {0} and {1} for these parameters to become {2},{3} and {4} ? [Less]
Posted over 11 years ago by JeremyS
Not sure I understand your question. Additional parameters can be accessed from within the message using numeric placeholders (such as {0}, {1}, {2} etc - like a format string). Is this what you mean?
Posted over 11 years ago by Looooooka
RuleFor(x => x.Password) .Length(1, 3).WithLocalizedMessage(()=> Demo.App_LocalResources.DataAnnotations.StringLength,new Object[] { "a", "b", "c" }); How can one make this work? The Length validator is passing the ... [More] parameters 1 and 3 and there is no way to pass other parameters to correctly build the message. Same problem with ".WithMessage". So how can one add other params? [Less]
Posted over 11 years ago by JeremyS
Strong naming doesn't really add any benefit, but makes dependency management more complex.
Posted over 11 years ago by chequan
Thanks very much. I noticed the following instructions: Please be aware that signed packages are not recommended, and will not be supported long-term. I want to know why not recommended? Thanks.
Posted over 11 years ago by JeremyS
Default build of FluentValidation is not strong-named. Install the strong-named version instead. See the signed packages section on this page: https://fluentvalidation.codeplex.com/wikipage?title=NuGet%20Packages&referringTitle=Home
Posted over 11 years ago by chequan
Assembly generation failed -- Referenced assembly 'FluentValidation.Mvc' does not have a strong name Assembly generation failed -- Referenced assembly 'FluentValidation' does not have a strong name
Posted over 11 years ago by roygi
Hi Jeremy: Thanks for the great reply that not only answer the question but also remind me of an important concept. J.
Posted over 11 years ago by JeremyS
I would say that a lot of it depends on finding a balance that you're happy with. When I first started out with TDD, I went very over-board with testing the interactions - I had very high code-coverage but my tests were very brittle, and would break ... [More] as soon as there was any refactoring. These days, I tend to write unit tests for critical or complex logic (business processes, validation rules etc) but I don't tend to write unit tests for controller layer - my controller layer is very thin and any issues would quickly be made visible via UI testing. But this is just my personal preference, and also varies from project-to-project. I've found that by having a very thin controller layer, the need to explicitly write tests for it becomes very minimal. If you are going to test the controller layer, then I would have tests that perhaps do the following (just an example): When a controller action is passed a valid model instance, the user is redirected to a success page When a controller action is passed an invalid model instance, the page is re-rendered and there are errors in the model-state (if you're using MVC for example) I personally don't tend to go any deeper than that. In your particular case, if you're finding that you're frequently forgetting to change the name of the ruleset, then I'd look at finding a way of using conventions to automatically work out the correct ruleset name (maybe based on the name of the controller action or something) rather than hard-coding it. This way your infrastructure is taking care of the problem. I'd say go as deep as it makes sense to do so for your particular project - only you can know how much value will be derived from doing this sort of testing. At the end of the day, as developers we have to provide value for the business - if all of our time is being spent re-writing tests because they're brittle then this isn't a good use of the business's money, or our time. All the best with the project, I hope you find a comfortable balance with the testing. Jeremy [Less]