
The benefits of using Feydra were pretty big so we began to wonder if there might still be a way to do this. As we looked into the Feydra code we realized it was using
VirtualPathViewEngine
as the view engine which inherited RazorViewEngine. Since we know the interface for this class we know it works just like any other view engine. So what if we had our view engine inherit from VirtualPathViewEngine? Could we add the same logic Feydra execute to decide if we needed to pass processing logic off to VirtualPathViewEngine? MyFedViewEngine : VirtualPathViewEngine
As it turns out the Feydra view engine just looks at a cookie of "FeydraUser" to decide if Feydra is enabled. This allows our view engine to do the processing it needs and then see if Feydra is enabled, when it is, we can pass the processing of the view off to Feydra's class. Now we have all the benefits of our view engine and Feydras. Inside the FindPartialView
method or the FindView
method we just need a little check this this to pass control off to the base class when Feydra is active. if (!string.IsNullOrEmpty(controllerContext.HttpContext.Request.Cookies["FeydraUser"]?.Value))
{
return base.FindPartialView(controllerContext, processedView, useCache);
}
Here is the catch to all this. We have now strongly coupled the Feydra assembly and class to our code. This means it needs to get deployed with our code. However, one thing you don't want to do, and the Hedgehog team advises against, is deploy Feydra code and assembly into production.This is where the power of Siteccore dependancy injection and rule based configurations help us a ton! We only want to deploy the Feydra enabled view engine to content delivery (CD) servers running for FED use. So we view that as having a CD server running in a new role of FED. For this all we did was use our deployment and build process to classify the FED CD servers and servers in the FED role. In your web.config set a value like this:
<add key="role:define" value="ContentDelivery, FED"/>
Now we have a way of knowing if the server is a FED server or not. Next comes setting up dependency injection so we can inject the view engine we want. In our project we have a Helix based solution with a RegisterContainer class for each project./// <summary> /// Registers all interfaces from this project to be used for injection /// </summary> public class RegisterContainer : IServicesConfigurator { /// <summary> /// Configures the specified service collection. /// </summary> /// <param name="serviceCollection">The service collection.</param> public void Configure(IServiceCollection serviceCollection) { serviceCollection.AddScoped<MyFedViewEngine, MyFedViewEngine>(); } }
Now we have the code that will register my view engine that uses Feydra. Next, we need to set up the configuration that will tell Sitecore to call this method. This is where we use our server role. Remember we only want this view engine to be used on FED servers, not production. In production, we don't want this code even on the server. So we separate this code into its own assembly and create this configuration for it.
1 2 3 4 5 6 7 8 | <configuration xmlns:patch="http://www.sitecore.net/xmlconfig/" xmlns:role="http://www.sitecore.net/xmlconfig/role/"> <sitecore role:require="FED"> <services> <configurator type="MyFEDTheming.RegisterContainer, MyFEDTheming" /> </services> </sitecore> </configuration> |
Notice on line 2 we have a role:require statement. This allows us to only configure this registration code if the server is running in the FED role. When it is not the registration code will never execute. This allows us to do the last magical step to make this work. In non-FED environments and in production you simply remove or don't deploy the Feydra assemblies as well as your assembly of MyFEDTheming. You just deploy your production ViewEngine and it's a configuration which is set up the same way only with its configuration on line 2 specifying it is not running in the FED role.
1 2 3 4 5 6 7 8 | <configuration xmlns:patch="http://www.sitecore.net/xmlconfig/" xmlns:role="http://www.sitecore.net/xmlconfig/role/"> <sitecore role:require="!FED"> <services> <configurator type="MyProdTheming.RegisterContainer, MyProdTheming" /> </services> </sitecore> </configuration> |
Because of the above config setting that utilizes the role, nothing ever tries to execute the FED code so it all runs great. I love it when a plan comes together!
Comments