Skip to content

Instantly share code, notes, and snippets.

@peaeater
Created May 8, 2020 22:05
Show Gist options
  • Save peaeater/03af51663732d3075be9c481dae48c38 to your computer and use it in GitHub Desktop.
Save peaeater/03af51663732d3075be9c481dae48c38 to your computer and use it in GitHub Desktop.
Castle Windsor and Web API 2 with ASP.NET MVC
using System.Web.Http;
using System.Web.Mvc;
using System.Web.Routing;
using Andi.MVC.Core;
using Andi.MVC.Core.Infrastructure.Globalization;
namespace Andi.MVC.Web
{
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
// MVC setup
AreaRegistration.RegisterAllAreas();
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
MvcHandler.DisableMvcResponseHeader = true;
// use globalized views if found
/* N.B. Globalization is based on routes, culture is set in BaseController */
ViewEngines.Engines.Clear();
ViewEngines.Engines.Add(new GlobalizedRazorViewEngine());
// Resolve IOC dependencies
IocContainer.Setup();
// Web API config
GlobalConfiguration.Configure(config =>
{
// set media route map
config.Routes.MapHttpRoute(
name: "Media",
routeTemplate: "media/{*filepath}",
defaults: new {controller = "MediaApi", filepath = RouteParameter.Optional});
});
}
protected void Application_End()
{
IocContainer.Stop();
}
}
}
using System.Threading;
using System.Web.Http;
using System.Web.Http.Dispatcher;
using System.Web.Mvc;
using Andi.MVC.Core.Infrastructure.DataAnnotations;
using Andi.MVC.Core.Infrastructure.IOC;
using Castle.Windsor;
using Castle.Windsor.Installer;
using FluentValidation.Mvc;
namespace Andi.MVC.Core
{
public static class IocContainer
{
private static IWindsorContainer _container;
public static void Setup()
{
_container = new WindsorContainer().Install(FromAssembly.This());
// mvc controller factory
var controllerFactory = new WindsorControllerFactory(_container.Kernel);
ControllerBuilder.Current.SetControllerFactory(controllerFactory);
// validator factory
DataAnnotationsModelValidatorProvider.AddImplicitRequiredAttributeForValueTypes = false;
var validatorProvider = new FluentValidationModelValidatorProvider(new WindsorFluentValidatorFactory(_container.Kernel))
{
AddImplicitRequiredValidator = false
};
// force MVC to use fluent validation
ModelValidatorProviders.Providers.Clear();
ModelValidatorProviders.Providers.Add(validatorProvider);
// force model metadata to use custom provider
ModelMetadataProviders.Current = new CustomModelMetadataProvider(validatorProvider.ValidatorFactory);
// resolve automapper maps
AutoMapperBootstrapper.Configure(_container);
//// web api controllers
GlobalConfiguration.Configuration.DependencyResolver = new WindsorDependencyResolver(_container.Kernel);
}
public static void Stop()
{
_container?.Dispose();
}
}
}
using System.Web.Mvc;
using Castle.MicroKernel.Registration;
using Castle.MicroKernel.SubSystems.Configuration;
using Castle.Windsor;
namespace Andi.MVC.Core.Infrastructure.IOC
{
public class MvcControllerInstaller : IWindsorInstaller
{
public void Install(IWindsorContainer container, IConfigurationStore store)
{
// Register controllers in the named assembly
container.Register(
Classes.FromAssemblyNamed("Andi.MVC.Web")
.BasedOn<IController>()
.ConfigureFor<IController>(x => x.LifestyleTransient()));
}
}
}
using System.Web.Http;
using Castle.MicroKernel.Registration;
using Castle.MicroKernel.SubSystems.Configuration;
using Castle.Windsor;
namespace Andi.MVC.Core.Infrastructure.IOC
{
public class WebApiControllerInstaller : IWindsorInstaller
{
public void Install(IWindsorContainer container, IConfigurationStore store)
{
container.Register(
Classes.FromAssemblyNamed("Andi.MVC.Web")
.BasedOn<ApiController>()
.ConfigureFor<ApiController>(x => x.LifestyleScoped()));
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Http.Dependencies;
using Castle.MicroKernel;
namespace Andi.MVC.Core.Infrastructure.IOC
{
internal class WindsorDependencyResolver : System.Web.Http.Dependencies.IDependencyResolver
{
private readonly IKernel _kernel;
public WindsorDependencyResolver(IKernel kernel)
{
_kernel = kernel;
}
public IDependencyScope BeginScope()
{
return new WindsorDependencyScope(_kernel);
}
public void Dispose()
{
}
public object GetService(Type serviceType)
{
return _kernel.HasComponent(serviceType) ? _kernel.Resolve(serviceType) : null;
}
public IEnumerable<object> GetServices(Type serviceType)
{
return _kernel.ResolveAll(serviceType).Cast<object>();
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Http.Dependencies;
using Castle.MicroKernel;
using Castle.MicroKernel.Lifestyle;
namespace Andi.MVC.Core.Infrastructure.IOC
{
public class WindsorDependencyScope : IDependencyScope
{
private readonly IKernel _kernel;
private readonly IDisposable _disposable;
public WindsorDependencyScope(IKernel kernel)
{
_kernel = kernel;
_disposable = kernel.BeginScope();
}
public void Dispose()
{
_disposable.Dispose();
}
public object GetService(Type serviceType)
{
return _kernel.HasComponent(serviceType) ? _kernel.Resolve(serviceType) : null;
}
public IEnumerable<object> GetServices(Type serviceType)
{
return _kernel.ResolveAll(serviceType).Cast<object>();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment