Create New Project
Install Necessary Packages
- Install-Package Autofac
- Install-Package Autofac.WebApi2
- Install-Package FluentValidation
- Install-Package FluentValidation.WebApi
- Install-Package Microsoft.AspNet.WebApi
- Install-Package Microsoft.AspNet.WebApi.Owin
- Install-Package Microsoft.Owin.Host.SystemWeb
- Install-Package Owin
- Install-Package Newtonsoft.Json
Create Partial Startup Classes
Partial class is just splitting class file into two or more files, and all parts are combined when the application is compiled.
It is used in a situation
- When working on large projects, spreading a class over separate files enables multiple programmers to work on it at the same time.
- When working with automatically generated source, code can be added to the class without having to recreate the source file. Visual Studio uses this approach when it creates Windows Forms, Web service wrapper code, and so on. You can create code that uses these classes without having to modify the file created by Visual Studio.
-
To split a class definition, use the
partial
keyword modifier
While adding this class our project structure looks like.
Startup.Autofac.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using Autofac; | |
using Autofac.Features.ResolveAnything; | |
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Web; | |
namespace FluentAutofacValidationAPI.App_Start | |
{ | |
public partial class Startup | |
{ | |
private static IContainer ConfigureAutofac() | |
{ | |
var builder = new ContainerBuilder(); | |
builder.RegisterModule<AutofacWebModule>(); | |
builder.RegisterSource(new AnyConcreteTypeNotAlreadyRegisteredSource()); | |
var container = builder.Build(); | |
return container; | |
} | |
} | |
} |
Startup.WebApi.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using Autofac; | |
using Autofac.Features.ResolveAnything; | |
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Web; | |
namespace FluentAutofacValidationAPI | |
{ | |
public partial class Startup | |
{ | |
private static IContainer ConfigureAutofac() | |
{ | |
var builder = new ContainerBuilder(); | |
builder.RegisterModule<AutofacWebModule>(); | |
builder.RegisterSource(new AnyConcreteTypeNotAlreadyRegisteredSource()); | |
var container = builder.Build(); | |
return container; | |
} | |
} | |
} |
Startup.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using Autofac; | |
using Autofac.Features.ResolveAnything; | |
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Web; | |
namespace FluentAutofacValidationAPI | |
{ | |
public partial class Startup | |
{ | |
private static IContainer ConfigureAutofac() | |
{ | |
var builder = new ContainerBuilder(); | |
builder.RegisterModule<AutofacWebModule>(); | |
builder.RegisterSource(new AnyConcreteTypeNotAlreadyRegisteredSource()); | |
var container = builder.Build(); | |
return container; | |
} | |
} | |
} |
Add Infrastructure classes
Now our Project structure looks like
AutofacValidatorFactory.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using Autofac; | |
using FluentValidation; | |
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Web; | |
namespace FluentAutofacValidationAPI.Infrastructure | |
{ | |
public class AutofacValidatorFactory : ValidatorFactoryBase | |
{ | |
private readonly IComponentContext _context; | |
public AutofacValidatorFactory(IComponentContext context) | |
{ | |
_context = context; | |
} | |
public override IValidator CreateInstance(Type validatorType) | |
{ | |
object instance; | |
if (_context.TryResolve(validatorType, out instance)) | |
{ | |
var validator = instance as IValidator; | |
return validator; | |
} | |
return null; | |
} | |
} | |
} |
AutofacWebModule.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using Autofac; | |
using Autofac.Integration.WebApi; | |
using FluentValidation; | |
using FluentValidation.WebApi; | |
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Web; | |
using System.Web.Http.Validation; | |
namespace FluentAutofacValidationAPI.Infrastructure | |
{ | |
public class AutofacWebModule : Module | |
{ | |
protected override void Load(ContainerBuilder builder) | |
{ | |
builder.RegisterApiControllers(ThisAssembly); | |
builder.RegisterAssemblyTypes(ThisAssembly) | |
.Where(t => t.Name.EndsWith("Validator")) | |
.AsImplementedInterfaces() | |
.InstancePerLifetimeScope(); | |
builder.RegisterType<FluentValidationModelValidatorProvider>().As<ModelValidatorProvider>(); | |
builder.RegisterType<AutofacValidatorFactory>().As<IValidatorFactory>().SingleInstance(); | |
base.Load(builder); | |
} | |
} | |
} |
ValidateFilterAttribute.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.Linq; | |
using System.Net; | |
using System.Net.Http; | |
using System.Web.Http.Controllers; | |
using System.Web.Http.Filters; | |
namespace FluentAutofacValidationAPI.Infrastructure | |
{ | |
public class ValidateFilterAttribute : ActionFilterAttribute | |
{ | |
public override void OnActionExecuting(HttpActionContext actionContext) | |
{ | |
if (!actionContext.ModelState.IsValid) | |
{ | |
actionContext.Response = | |
actionContext.Request.CreateErrorResponse(HttpStatusCode.BadRequest, actionContext.ModelState); | |
} | |
else if (actionContext.ActionArguments.FirstOrDefault().Value == null) | |
{ | |
actionContext.ModelState.AddModelError("Model Null", "Form is empty. Please enter some value"); | |
actionContext.Response = | |
actionContext.Request.CreateErrorResponse(HttpStatusCode.BadRequest, actionContext.ModelState); | |
} | |
base.OnActionExecuting(actionContext); | |
} | |
} | |
} |
Add Modal Validation and Controller
Now our Project structure looks like
Controller
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using FluentAutofacValidationAPI.Infrastructure; | |
using FluentAutofacValidationAPI.Models; | |
using System.Web.Http; | |
namespace FluentAutofacValidationAPI.Controllers | |
{ | |
[RoutePrefix("api/people")] | |
public class PeopleController : ApiController | |
{ | |
[HttpPost] | |
[Route("create")] | |
[ValidateFilter] | |
public IHttpActionResult CreatePerson(Person person) | |
{ | |
return Ok("ok"); | |
} | |
} | |
} |
Model and Model Validation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using FluentValidation; | |
namespace FluentAutofacValidationAPI.Models | |
{ | |
public class PersonValidator : AbstractValidator<Person> | |
{ | |
public PersonValidator() | |
{ | |
RuleFor(x => x.FirstName).NotEmpty(); | |
RuleFor(x => x.LastName).NotEmpty(); | |
} | |
} | |
public class Person | |
{ | |
public string FirstName { get; set; } | |
public string OtherNames { get; set; } | |
public string LastName { get; set; } | |
} | |
} |
Finally test our code
Thanks,
Download Code
Hi... If you add a dependency in the validator constructor (PersonValidator), it throws a exception:
ReplyDeleteAn exception of type 'Autofac.Core.DependencyResolutionException' occurred in Autofac.dll but was not handled in user code
Additional information: None of the constructors found with 'Autofac.Core.Activators.Reflection.DefaultConstructorFinder' on type 'FluentAutofacValidationAPI.Models.PersonValidator' can be invoked with the available services and parameters:
Cannot resolve parameter 'FluentAutofacValidationAPI.Infrastructure.IStudentService service' of constructor 'Void .ctor(FluentAutofacValidationAPI.Infrastructure.IStudentService)'.