Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • Alex Perotti 53 posts 94 karma points
    Aug 14, 2015 @ 10:33
    Alex Perotti
    0

    Umbraco dynamic routing

    Hi everyone,

    I'm developing a website using Glass.Mapper and Castle.Windsor

    My goal is to develop a site which is skinnable, so I want to use different controllers for a given url based on a configuration parameter.

    For example: for the document type TestType

    I want to dynamically choose the controller TestTypeController which exist in two different namespaces, based on a configuration parameter.

    Someone can point me out how to correctly work with the umbraco pipeline?

    Thank you very much :)

  • Lars-Erik Aabech 349 posts 1100 karma points MVP 7x c-trib
    Aug 14, 2015 @ 14:18
    Lars-Erik Aabech
    0

    See the bottom part about creating a filteredcontrollerfactory here: https://our.umbraco.org/documentation/Reference/Templating/Mvc/using-ioc

  • Alex Perotti 53 posts 94 karma points
    Aug 15, 2015 @ 03:04
    Alex Perotti
    0

    Hi Lars,

    thank you for your answer. I had already followed the indications during the setup of my solution.

    At this point I'm a bit confused...

    So, global.asax is

    public class Global : UmbracoApplication
    {
        public static IWindsorContainer Container;
    
        protected override void OnApplicationStarting(object sender, EventArgs e)
        {
            base.OnApplicationStarting(sender, e);
            Bootstrap.BootstrapApplication();
        }
    
        protected override void OnApplicationStarted(object sender, EventArgs e)
        {
            base.OnApplicationStarted(sender, e);
            var bundles = Container.Kernel.ResolveAll<IBundleInstaller>();
            foreach (var b in bundles)
            {
                b.Install(BundleTable.Bundles);
    
            }
    
            Routes.RegisterRoutes(RouteTable.Routes);
        }
    
        protected override void OnApplicationEnd(object sender, EventArgs e)
        {
            base.OnApplicationEnd(sender, e);
            Container.Dispose();
        }
    }
    

    The bootstrap class

    public static class Bootstrap
    {
        public static void BootstrapApplication()
        {
            Global.Container = new WindsorContainer()
                .Install(FromAssembly.This(),
                   FromAssembly.Named("Umb.Firenze")
                );
    
    
            DependencyResolver.SetResolver(new WindsorDependencyResolver(Global.Container.Kernel));
            GlobalConfiguration.Configuration.Services.Replace(typeof(IHttpControllerActivator), new WindsorCompositionRoot(Global.Container));
            FilteredControllerFactoriesResolver.Current.InsertType<FilteredControllerFactory>(0);
    
    
        }
    
    }
    

    WindsorDependencyResolver

    public class WindsorDependencyResolver : System.Web.Mvc.IDependencyResolver
    {
    
        private readonly IKernel kernel;
    
    
        public WindsorDependencyResolver(IKernel kernel)
        {
            this.kernel = kernel;
        }
    
    
        public object GetService(Type serviceType)
        {
            return this.kernel.HasComponent(serviceType) ? this.kernel.Resolve(serviceType) : null;
        }
    
    
        public IEnumerable<object> GetServices(Type serviceType)
        {
            return this.kernel.ResolveAll(serviceType) as IEnumerable<object>;
        }
    
    }
    
  • Alex Perotti 53 posts 94 karma points
    Aug 15, 2015 @ 03:06
    Alex Perotti
    0

    Some other code

     public class WindsorCompositionRoot : IHttpControllerActivator
    {
        private readonly IWindsorContainer objectFactory;
    
        public WindsorCompositionRoot(IWindsorContainer objectFactory)
        {
            this.objectFactory = objectFactory;
        }
    
        public IHttpController Create(HttpRequestMessage request,
                                      HttpControllerDescriptor controllerDescriptor,
                                      Type controllerType)
        {
    
            if (IsUmbracoController(controllerType))
            {
                return Activator.CreateInstance(controllerType) as IHttpController;
            }
    
            var controller = (IHttpController)objectFactory.Resolve(controllerType);
    
            request.RegisterForDispose(new Release(() => objectFactory.Release(controller)));
    
            return controller;
        }
    
    
    
        public static bool IsUmbracoController(Type controllerType)
        {
            return controllerType.Namespace != null
                && controllerType.Namespace.StartsWith("umbraco", StringComparison.InvariantCultureIgnoreCase)
                && !controllerType.Namespace.StartsWith("umbraco.extensions", StringComparison.InvariantCultureIgnoreCase);
        }
    
    
        private class Release : IDisposable
        {
            private readonly Action release;
    
            public Release(Action release)
            {
                this.release = release;
            }
    
            public void Dispose()
            {
                this.release();
            }
        }
    }
    
    public class FilteredControllerFactory : WindsorControllerFactory, IFilteredControllerFactory
    {
        public FilteredControllerFactory(IKernel kernel) : base(kernel)
        {
    
        }
    
        public bool CanHandle(RequestContext request)
        {
            Type controllerType = GetControllerType(request, request.RouteData.Values["controller"].ToString());
            return Global.Container.Kernel.HasComponent(controllerType);
        }
    }
    

    And finally the route table

    public static class Routes
    {   
        public static void RegisterRoutes(RouteCollection routes)
        {
            routes.MapRoute(
            "Macro",
            "Macro/{controller}/{action}/{id}",
    
            new
            {
                controller = "TestMacro",
                action = "Index",
                id = UrlParameter.Optional
            });
    
    
        }
    }
    
  • Alex Perotti 53 posts 94 karma points
    Aug 15, 2015 @ 03:10
    Alex Perotti
    0

    If I run in debug mode, the filtered controller factory seems to never fire.

    I dug a bit into this and maybe I have some clues.

    I've copied the Umbraco.Web.Mvc.MasterControllerFactory from the source code, changed the namespace and set as my default factory to go in there in debug bug.

    It seems that FilteredControllerFactoriesResolver.Factory contains only the default umbraco value (Umbraco.Web.Mvc.RenderControllerFactory), while my custom controller factory in only registered in InstanceTypes, thus never invoked.

    I have no idea why or what should i do to fix this...

  • Alex Perotti 53 posts 94 karma points
    Aug 15, 2015 @ 04:37
    Alex Perotti
    0

    Finally i got the solution!

    The problem was on my FilteredControllerFactory, that needed a parameterless controller.

    I solved the issue changing the .ctor like this

    public FilteredControllerFactory() : base(Global.Container.Kernel) { }

Please Sign in or register to post replies

Write your reply to:

Draft