This project is read-only.

Simple Injector and Umbraco

Mar 13, 2015 at 4:34 PM
Edited Mar 13, 2015 at 4:37 PM
Hello,

I was using Autofac in an Umbraco-based project and after hearing good things about Simple Injector and wanting to make some architectural changes, I tried switching and ran into some problems.

I receive the error:
No registration for type RenderMvcController could be found and an implicit registration could not be made. For the container to be able to create RenderMvcController, it should contain exactly one public constructor, but it has 2.
Here is my configuration code:
            // Configure Simple Injector
            // 1. Create a new Simple Injector container
            var container = new Container();
            container.RegisterMvcControllers(typeof(Global).Assembly);

            // 2. Configure the container (register)
            // See below for more configuration examples

            container.Register<IDbContextScopeFactory, DbContextScopeFactory>(Lifestyle.Transient);
            container.Register<IAmbientDbContextLocator, AmbientDbContextLocator>(Lifestyle.Singleton);

            // 3. Optionally verify the container's configuration.
            container.Verify();

            // 4. Store the container for use by the application
            DependencyResolver.SetResolver(
                new SimpleInjectorDependencyResolver(container));
Here is the working Autofac configuration:
            // Register umbraco context, mvc controllers and api controllers
            builder.Register(c => UmbracoContext.Current).AsSelf();
            builder.RegisterControllers(Assembly.GetExecutingAssembly());
            builder.RegisterApiControllers(typeof(UmbracoApplication).Assembly);

            // Register application specific types 
            RegisterTypes(builder);

            var container = builder.Build();
            var resolver = new AutofacWebApiDependencyResolver(container);
            GlobalConfiguration.Configuration.DependencyResolver = resolver;
            DependencyResolver.SetResolver(new AutofacDependencyResolver(container));

        private static void RegisterTypes(ContainerBuilder builder)
        {
            builder.RegisterType<DbContextScopeFactory>().As<IDbContextScopeFactory>();
            builder.RegisterType<JobBoardRepository>().As<IJobBoardRepository>();
            builder.RegisterType<BusinessEntityRepository>().As<IBusinessEntityRepository>();
            builder.RegisterType<EmploymentApplicationRepository>().As<IEmploymentApplicationRepository>();
            builder.RegisterType<LookupRepository>().As<ILookupRepository>();
            builder.RegisterType<AmbientDbContextLocator>().As<IAmbientDbContextLocator>();
        }
Am I doing something wrong, or is it really not possible to use Simple Injector here because of the multiple constructors in Umbraco's RenderMvcController?

Thanks
Mar 13, 2015 at 4:38 PM
Your controller has two constructors and this is an anti-pattern, as described in detail here.
Mar 13, 2015 at 5:15 PM
Hi,

Thanks for reply.

It's not my controller - it's a class built into Umbraco (it's an open source CMS for .NET).

Bottom line is I cannot use Simple Injector then?
Mar 13, 2015 at 5:30 PM
Edited Mar 14, 2015 at 10:22 AM
Hi Kidmeke,

Of course you can Simple Injector. Read the article again; especially the part about framework types. The only thing you have to do is register the Umbraco controllers explicitly using a delegate. Another option is to override the constructor resolution behavior, but my advice is to not do that and stick to the advice given in the article, which is:
Prevent using your container’s auto-wiring facility when registering 3rd party types.
Mar 13, 2015 at 7:00 PM
Wait, let me rephrase that. How many controllers does Umbraco have that you need? Is it just a few, I would opt for registering them by hand. If there are dozens and/or they add new controllers regularly, overriding Simple Injector's constructor resolution behavior might be a good option after all. But before overriding the constructor resolution behavior, you have to find out what Umbraco's strategy is with constructors. How do you select the proper constructor? Once you know, it will be trivial to write a IConstructorResolutionBehavior implementation for that.
Mar 14, 2015 at 5:14 AM
Ah, I see now! Thank you very much. I didn't read the linked article at first ;) because I thought you were flat out saying it couldn't be done!

To answer your question, I believe Umbraco has two controller types that I need, so I will go for registering them by hand.

By the way, I was looking into Simple Injector because I am making some architecture changes based on one of your blog posts that I found being praised on another blog. Your articles are quite frankly wonderful. I am truly grateful for the depth and intelligence of your articles and I am learning a great deal.

I hope you know how helpful they are.
Mar 14, 2015 at 10:26 AM
I'm sorry to have mislead you. There is little that can't be done with Simple Injector. Sometimes however you need to think differently. I'm glad you like me blog posts. If you have any further questions about Simple Injector, feel free to post new questions here at codeplex, or stackoverflow. Whatever suits best.

Cheers

Steven