Skip to content

Instantly share code, notes, and snippets.

@thecodefish
Last active July 3, 2017 02:40
Show Gist options
  • Save thecodefish/5b33e9d11ca99f832927 to your computer and use it in GitHub Desktop.
Save thecodefish/5b33e9d11ca99f832927 to your computer and use it in GitHub Desktop.
Code classes/snippets required for setting up Castle.Windsor integration with Umbraco 7.x
using System.Web.Http;
using System.Web.Http.Dispatcher;
using Umbraco.Core;
using Umbraco.Web.Mvc;
namespace MySite.CastleConfiguration
{
public class ApplicationEventHandler : IApplicationEventHandler
{
public void OnApplicationInitialized(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext)
{ }
public void OnApplicationStarting(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext)
{
//MVC
FilteredControllerFactoriesResolver.Current.InsertType<WindsorControllerFactory>(0);
//WebAPI
GlobalConfiguration.Configuration.Services.Replace(typeof(IHttpControllerActivator), new WindsorCompositionRoot());
}
public void OnApplicationStarted(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext)
{ }
}
}
using System.Web.Http.Controllers;
using System.Web.Mvc;
using Castle.MicroKernel.Registration;
using Castle.MicroKernel.SubSystems.Configuration;
using Castle.Windsor;
using Umbraco.Web.Editors;
namespace MySite.CastleConfiguration.Installers
{
public class ControllersInstaller : IWindsorInstaller
{
public void Install(IWindsorContainer container, IConfigurationStore store)
{
container.Register(Classes.FromThisAssembly()
.BasedOn<IController>()
.LifestyleTransient());
}
}
}
using Castle.Windsor;
using Castle.Windsor.Installer;
namespace MySite.CastleConfiguration
{
public static class ServiceLocator
{
private static IWindsorContainer _container;
public static IWindsorContainer Current
{
get
{
if (_container == null)
{
_container = new WindsorContainer()
.Install(FromAssembly.This());
}
return _container;
}
}
}
}
using System;
using System.Net.Http;
using System.Web.Http.Controllers;
using System.Web.Http.Dispatcher;
using Castle.Windsor;
namespace MySite.CastleConfiguration
{
public class WindsorCompositionRoot : IHttpControllerActivator
{
private readonly IWindsorContainer _container;
private readonly IHttpControllerActivator _defaultControllerActivator;
public WindsorCompositionRoot()
{
_container = ServiceLocator.Current;
_defaultControllerActivator = new DefaultHttpControllerActivator();
}
public IHttpController Create(HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType)
{
//if the type is not one of our own, don't try and use dependency injection
//this fixes problems in the Umbraco back-end
if (IsThirdPartyController(controllerType))
{
return _defaultControllerActivator.Create(request, controllerDescriptor, controllerType);
}
IHttpController controller = (IHttpController) _container.Resolve(controllerType);
request.RegisterForDispose(new Release(() => _container.Release(controller)));
return controller;
}
private bool IsThirdPartyController(Type controllerType)
{
return controllerType.Namespace == null ||
!controllerType.Namespace.StartsWith("MySite", StringComparison.InvariantCultureIgnoreCase);
}
private class Release : IDisposable
{
private readonly Action _release;
public Release(Action release)
{
_release = release;
}
public void Dispose()
{
_release();
}
}
}
}
using System;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
using Castle.MicroKernel;
using Umbraco.Web.Mvc;
namespace MySite.CastleConfiguration
{
public class WindsorControllerFactory : DefaultControllerFactory, IFilteredControllerFactory
{
private readonly IKernel _kernel;
public WindsorControllerFactory()
{
_kernel = ServiceLocator.Current.Kernel;
}
public WindsorControllerFactory(IKernel kernel)
{
_kernel = kernel;
}
protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
{
if (controllerType == null)
{
throw new HttpException(404, string.Format("The controller for path '{0}' could not be found.", requestContext.HttpContext.Request.Path));
}
var controller = (Controller)_kernel.Resolve(controllerType);
//if (controller != null)
//{
// controller.ActionInvoker = _kernel.Resolve<IActionInvoker>();
//}
return controller;
}
public override void ReleaseController(IController controller)
{
_kernel.ReleaseComponent(controller);
}
public bool CanHandle(RequestContext request)
{
Type controllerType = GetControllerType(request, request.RouteData.Values["controller"].ToString());
return _kernel.HasComponent(controllerType);
}
}
}
@rocifier
Copy link

rocifier commented Jul 3, 2017

To get this to work with UmbracoApiController implementations I had to add this to the ControllersInstaller.cs:

        container.Register(Classes.FromThisAssembly()
            .BasedOn<IHttpController>()
            .If(t => t.Name.EndsWith("Controller"))
            .LifestyleTransient());

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment