IIS 7.5 included new Application Autostart functionality. With Autostart, IIS Applications can do things like build a cache or perform some other time-intensive process during an Application’s AppPool startup. I’ve used Autostart to activate long-running Task Parallel LibraryTasks and Timers. Autostart configuration requires changes to the ApplicationHost configuration, and while Autostart configuration is not complicated, it’s also not intuitive. What follows is a recipe that couples Autostart to Managed Extensibility Framework (MEF) making configuration easier and code more maintainable.
Coding Autostart
Coding Autostart is straightforward. Simply implement the IProcessHostPreloadClient interface contained in the System.Web assembly and coding is done. Following is an IProcessHostPreloadClient implementation.
public sealed class PreloadWeb : IProcessHostPreloadClient { #region IProcessHostPreloadClient Members public void Preload(string[] parameters) { Task.Factory.StartNew(() => { //Do something interesting } ,TaskCreationOptions.LongRunning); } #endregion }
IProcessHostPreloadClient contains one method. The method is invoked when the Application’s AppPool is activated and the Application AppDomain is created. The interesting implementation detail is what a developer chooses to do in the method. Following are some AutoStart implementation scenarios.
- As demonstrated in the example, an application may need to start a Thread, Timer, or Long Running Task. The Task may poll an external resource like a SQL Server database or periodically refresh a data cache.
- The Canonical Autostart example is that it executes a time-consuming process. For example: Web Services must often be responsive. Running a time-consuming process when an EndPoint is first tickled may not be realistic if, for example, a Web Service has some sort of time-sensitive service level response time agreement.
Coding Autostart is almost trivial. In fact, configuring Autostart is the most difficult Autostart implementation task.
Configuring Autostart
Though the IIS GUI Administration tool tries to unify the configuration process, IIS configuration is stored across multiple Configuration files. When configuring Autostart, for deployment and troubleshooting reasons it’s important to recognize which configuration is being modified. Most of the Autostart configuration lives in the Applicationhost.config located under C:\Windows\System32\inetsrv\config.
Following is how Autostart is configured in the GUI Administration.
The first step, highlight the Admin server root and select Configuration Management.
Configuration Editor
Code implementing the IProcessHostPreloadClient is called a service Autostart provider. To make IIS aware of the provider, navigate to the following location.
AutoStartProviders
Select the location from the drop-down menu.
Once Autostart Providers is selected, add a new Autostart Provider. The Autostart Provider setup screen will look like the following.
ClassAndAssembly
Remember the Provider name because it will be used to configure the Provider on the site. Enter the class and the assembly containing the class. Notice how the assembly name omits the DLL extension and the class includes the namespace. When Autostart activates, IIS will look for what is configured here in the application’s bin directory.
Next navigate to “Sites” just below ServiceAutoStartProviders in the following location.
App Host Sites
This is where Autostart is enabled on the Site. Make sure IIS is setup with the .NET 4.0 Framework. Be sure that the site is configured for a .NET 4.0 Application Pool and that the AppPool is set to autoStart. AutoStart is on the AppPool properties.
AppPool is set to autoStart
Click on the collection and select the site to configure. The dialog looks something like the following.
Select the site to configure
Set the following properties. Use the Provider name configured earlier in the process.
Configure Site for AutoStart
That covers configuring and developing Autostart. Managed Extensibility Framework (MEF) cannot eliminate configuration. MEF can, however, make configuration more consistent and make code more maintainable. First, though, a quick MEF review.
MEF Overview
MEF includes classes and attributes that support component discovery and extensibility. MEF allows applications to load components without baking references into the compiled application. Two simple ideas underlie MEF solutions.
- Components providing functionality are called “Exports”.
- Components “consuming” an “Export” are called “Imports”.
So, for example, a class within an assembly may “export” functionality that another class in another assembly “imports”.
Some core MEF components are described below:
- Import and Export attributes designate the components a developer will consume or provide.
- A CompositionContainer gathers the exports and matches exports to imports. CompositionContainers can, for example, instantiate class instances and apply the instance on a class Property.
- CompositionContainers read from Catalogs. MEF components can be housed in Directories and Assemblies. A CompositionContainer works through, for example, a DirectoryCatalog to gather all MEF components in a Directory.
Turning back to Autostart; the final few steps demonstrate how to couple MEF to Autostart and why MEF is important to maintainability.
Enabling MEF
The following is the Autostart IProcessHostPreloadClient implementation using MEF.
public sealed class PreloadWeb : IProcessHostPreloadClient { #region IProcessHostPreloadClient Members public void Preload(string[] parameters) { //MEF code var catalog = new DirectoryCatalog( AppDomain.CurrentDomain.BaseDirectory + "bin"); using (var container = new CompositionContainer(catalog)) { container.ComposeParts(this); } } #endregion }
IIS application components are contained in the bin folder. The CompositionContainer gathers the components from the bin folder and applies instances to the PreloadWeb class. MEF can be implemented a number of different ways.
One straight-forward approach is to create a common Interface, implement the interface, and then Export it using an MEF attribute. If a developer has multiple sites with different Autostart needs MEF would enable a single Provider for all sites. The bin on each site would contain a common Preload assembly containing the interface and the IProcessHostPreloadClient code.
At first glance MEF may appear to be overkill. However, consider the following benefits.
First consider Separation of concerns. Implementing IProcessHostPreloadClient requires the System.Web assembly. The assembly includes ASP.NET specific components. Including the reference means that, for example, a Core assembly is yoked to ASP.NET specific components. Separating an application into a Core and layering server specific features on it is an architecture and maintainability best practice.
While MEF is not required to achieve separation of concerns, consider reusability. If your organization has even a handful of sites, an administrator will be responsible for configuring each site. The MEF implementation would eliminate the need to create the serviceAutostartProvider entries. For example, instead of 10 serviceAutoStartProvider entries for 10 sites only one entry is needed with the MEF implementation.
Conclusion
The new IIS 7.5 Autostart feature enables functionality that would’ve required creative thinking to implement in prior IIS versions. MEF within Autostart code can separate IIS specific code from the rest of an application achieving a more reusable and maintainable implementation.
Resources
http://www.iis.net/ConfigReference/system.applicationHost/applicationPools
http://blogs.msdn.com/b/momalek/archive/2011/05/12/writing-an-iis-7-5-auto-start-provider.aspx