Johan Björnfot
Feb 12, 2010
  8401
(1 votes)

Mirroring – Modules and Custom code

In this post I will go into more detail about how the mirroring service works and how that affects modules and custom code.

As I mentioned in my previous post the mirroring job is executed in a separate application from the site. This has some implications when it comes to modules and external code. For example if you use custom properties on your site then the assembly containing the custom properties must be loadable from the mirroring service. So you have to deploy the assemblies to the bin folder for the mirroring service.

Event handlers

Another thing to be aware of is how to attach custom event handlers, e.g. to hookup to DataFactory events. Before I give any recommendations a short description of the internals of MirroringService is needed.

Each time the mirroring service starts a mirroring job (either acting as a source or as a target) it will create a new AppDomain and initialize a “CMS runtime” inside the new AppDomain. With “CMS runtime” I mean that functions such as DataFactory, DynamicDataStore, ObjectStore, VirtualPathProviders etc are initialized and functional. The initialization works in the way that the service reads the site configuration and initializes the functions according to the configuration. After the mirroring job is finished the AppDomain is unloaded.

One reason a new AppDomain is created for a mirroring job is that then one mirroring service can serve several sites and handle concurrent jobs. That means for example that when there are several sites in an enterprise scenario they can share the same mirroring service (they can though be configured to use separate mirroring services if that is preferred). Another reason is that we want the service to be “stateless”, that is it holds no internal state. It gets a job request and then initializes the runtime, executes the job and when the job is finished everything is cleared and no state is saved inside the service.

During the initialization of the new AppDomain the mirroring service will scan the bin folder for assemblies that want to be part of initialization. The scanning will be performed both for PlugInAttribute and for new MEF initialization as described in New initialization.

So what about hooking up event handlers? The way to go is to either use the new MEF initialization (recommended) or use the PlugInAttribute with a static Start method. Using HttpModule will however not work. The reason for that is because even though the Init method of your HttpModule will be called, that code will not execute in the correct AppDomain meaning there is no way to access e.g. the initialized DataFactory.

Web context

Another thing to be aware of is that the code executed as part of the mirroring job executes without web context. That means that event handlers and other code need to be implemented so they can execute without web context. There are helper classes like EPiServer.Web.VirtualPathUtilityEx (works like System.Web.VirtualPathUtility) and EPiServer.Web.Hosting.GenericHostingEnvironment (works like System.Web.Hosting.HostingEnvironment) that can be used instead of their counterparts in .NET framework. They are designed to work as the .NET classes but they also works without web context. For example:

  • System.Web.VirtualPathUtility.ToAbsolute(virtualPath) can be replaced with EPiServer.Web.VirtualPathUtilityEx.ToAbsolute(virtualPath)
  • System.Web.HostingEnvironment.VirtualPathProvider.GetFile(virtualPath) can be replaced with EPiServer.Web.GenericHostingEnvironment.VirtualPathProvider.GetFile(virtualPath)

Service location

The installer will install the mirroring service in a folder called MirroringService under the site root. It will be configured as a seperate site in IIS with a separate AppPool which means that it runs in its own process. It is possible to manually copy the MirroringService to another server and set up an IIS site there pointing to the service folder. One thing to remember if the mirroring service is relocated to another machine is that the VirtualPathProviders for the site must be configured so they can accessed from both site and service. This typically means that you would configure them to use a file share. Another thing that needs to be changed if the mirroring service is relocated to another machine is that the WCF endpoints and protocol used for communication between service and site (event replication and source service endpoint) has to be reconfigured to the new location and the binding has to be changed from from net.pipe to something (e.g. net.tcp) that works between machines.

Feb 12, 2010

Comments

Please login to comment.
Latest blogs
From Prompting to Production: Optimizely Opal University Cohort and the Future of Agentic MarTech

Most organizations today are still playing with AI. They experiment with prompts, test ideas in isolated chats, and occasionally automate a task or...

Augusto Davalos | Apr 28, 2026

Six Compelling Reasons for Upgrading to CMS 13

Most software updates ask you to keep up. Optimizely CMS 13 asks something different — it asks whether your digital strategy is built for a world...

Muhammad Talha | Apr 28, 2026

Optimizely CMS 13 breaking changes: GetContentTypePropertyDisplayName

When upgrading from CMS 12 to 13, resolving property display names may not work as before. Here’s what changed.

Tomas Hensrud Gulla | Apr 27, 2026 |

Accelerate Optimizely DAM Adoption: Unlocking Business Value with Metadata Bulk Import

Accelerating Optimizely DAM Adoption How a Metadata-Driven Bulk Import Utility Unlocks Real Business Value Executive Summary For enterprises runnin...

Vaibhav | Apr 27, 2026