Sitecore 8.1 to work with the latest tools: Solr Server v6, Autofac v3.5, and Glass Mapper v4.
Initial Setup
Let's started off with a vanilla install of Sitecore 8.1 Update 2.
- Sitecore 8.1 Update 2 – MVC
- Distributed CM and CD
- Team Development for Sitecore (TDS)
- Used for T4 Code Generation and Serialization
- Visual Studio Project with Web Publishing to my local instances
- IIS / .NET 4.5
- SQL Server 2014 Dev Edition
Let's use the Sitecore Instance Manager (SIM) Installer or the Sitecore installer to install Sitecore.
For TDS see the recommended reading section at the end for some guidance links.
Adding in Autofac
The first step is adding Autofac to the Visual Studio project.
Note: Using NuGet Package Manager in Visual Studio, add Autofac to your Visual Studio project libraries and make sure that Autofac is registered as a reference in each project that you need it.
About Project Libraries
Project Configure:
- Domain Project
- Contains Models, domain-specific extension methods, and helpers.
- Let's store core business logic methods and classes in here too unless having separate projects (for purposes of DI) makes more sense.
- Framework Project
- Contains integration classes and hooks for integrating various frameworks into the solution.
- Services Project
- Where web service hooks and API classes are contained.
- Website Project
- The Website project to store Sitecore configs, views, supporting front-end files, etc.
- And two TDS projects for Sitecore Master and Core databases.
Connecting Autofac to Sitecore
In simple .NET implementations of Autofac, the Dependency Resolver is registered in the Global.asax.cs.
To get started, there are 3 major components to wiring up Autofac to Sitecore:
- Autofac Container Factory
- Autofac Controller Factory
- Custom Sitecore Initialize Pipeline
Autofac Container Factory
Note: Create and implement the Autofac Container Factory
The container factory is the primary location where the container gets built.
Remember that in Dependency Injection we only want one container to manage all of our dependencies.
The container factory takes the place of registering within the Global.asax.cs.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | using System; using Autofac; using Autofac.Integration.Mvc; namespace SiteCoria.Framework.DependencyInjection.Autofac.Factory { public class AutofacContainerFactory { public IContainer Create() { var builder = new ContainerBuilder(); // Register All Controllers In The Current Scope builder.RegisterControllers(AppDomain.CurrentDomain.GetAssemblies()); // Register Additional Controllers, Modules, etc //... //Build the Container return builder.Build(); } } } |
Autofac Controller Factory
Note: Create and implement the Autofac Controller Factory
The controller factory has two functions:
(A) Controller Resolution
(B) Controller Release
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | using System; using System.Web; using System.Web.Mvc; using System.Web.Routing; namespace SiteCoria.Framework.DependencyInjection.Autofac.Factory { public class AutofacControllerFactory : DefaultControllerFactory { protected override IController GetControllerInstance(RequestContext context, Type controllerType) { if (context == null ) { throw new ArgumentNullException(nameof(context)); } if (controllerType == null ) { throw new HttpException(404, string .Format( "No Controller Type Found For Path {0}" , context.HttpContext.Request.Path)); } var controller = (IController)DependencyResolver.Current.GetService(controllerType); if (controller != null ) return controller; throw new HttpException(404, string .Format( "No Controller Type: {0} Found For Path {1}" , controllerType.FullName,context.HttpContext.Request.Path)); } public override void ReleaseController(IController controller) { } } } |
This is a pretty basic implementation of the DefaultControllerFactory class.
Additional logging can easily be added here for a more in-depth analysis of missing controllers or another wizardry.
Custom Sitecore Initialize Pipeline
Note: Create and implement a Sitecore Pipeline Processor
The next step to implementing Autofac for Sitecore is to connect the container factory above to the Sitecore controller initialization.
Create a Sitecore pipeline processor that sets the Dependency Resolver to our newly created Autofac container.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | using System; using System.Web.Mvc; using Autofac.Integration.Mvc; using SiteCoria.Framework.DependencyInjection.Autofac.Factory; using Sitecore.Pipelines; namespace SiteCoria.Framework.DependencyInjection.Sitecore.Pipelines { public class InitializeAutofacControllerFactory { public virtual void Process(PipelineArgs args) { SetControllerFactory(args); } private void SetControllerFactory(PipelineArgs args) { if (args == null ) throw new ArgumentNullException(nameof(args)); var containerFactory = new AutofacContainerFactory(); var container = containerFactory.Create(); DependencyResolver.SetResolver( new AutofacDependencyResolver(container)); var controllerFactory = new AutofacControllerFactory(); ControllerBuilder.Current.SetControllerFactory(controllerFactory); } } } |
In typical DI implementations, setting the DependencyResolver typically occurs very near to the Application Start method of the application (e.g. Global.asax.cs).
However, because we are creating a Sitecore initialize pipeline processor, it’s close enough.
This processor does three things:
- Creates and builds the Autofac IoC container.
- Sets the MVC Dependency Resolver context.
- Initializes and sets the Sitecore ControllerBuilder context.
Note: Create Sitecore Patch Config to utilize new Controller Processor
- This is the last step in setting up Autofac 3.5+ on Sitecore. It’s a pretty basic patch config file.
- We need to replace the Sitecore.Mvc.Pipelines.Loader.InitializeControllerFactory with our new Autofac controller factory.
1 2 3 4 5 6 7 8 9 10 11 12 13 | <? xml version = "1.0" ?> < configuration xmlns:patch = "http://www.sitecore.net/xmlconfig/" > < sitecore > < pipelines > < initialize > < processor type = "SiteCoria.Framework.DependencyInjection.Sitecore.Pipelines.InitializeAutofacControllerFactory, SiteCoria.Framework" patch:before = "*[@type='Sitecore.Mvc.Pipelines.Loader.InitializeControllerFactory, Sitecore.Mvc']" /> < processor type = "Sitecore.Mvc.Pipelines.Loader.InitializeControllerFactory, Sitecore.Mvc" > < patch:delete /> </ processor > </ initialize > </ pipelines > </ sitecore > </ configuration > |
Compile and deploy your solution and Sitecore MVC will now be running as an Autofac Managed Application.
Recommended Reading
- HOW NOT TO DO DEPENDENCY INJECTION – THE STATIC OR SINGLETON CONTAINER
- Sitecore MVC Autofac Dependency Resolution
- Getting Started with TDS and Sitecore
Comments
Post a Comment