Loading types at runtime
I have a library that contains a factory, which creates instances of a type that implement an interface. Currently the factory, interface, and the implementations are in the same assembly. For maintainability, I’d like to separate the implementations from the core library and put them into their own assemblies. This will allow me to version each implementation independently from the core library. Any applications that need to use certain implementations will simply need to reference the core library and any number of libraries that contain the implementations. The factory in the core library should be able to determine which implementations are available at runtime.
Here I have a class library Demo.Core that contains an interface definition and a factory. There are no implementations for IPrinter in the core library. I have two additional class libraries called Demo.GreenPrinter and Demo.RedPrinter that contains implementations for IPrinter. The two libraries that contain the implementations references the core library, but the core library does not reference either of the libraries that contain the implementations. The console application needs to references the core library and at least one of the additional libraries.

The interface contains two methods. CanHandle contains logic to determine if a printer should be used and the Print method prints the message to the screen.
public interface IPrinter
{
bool CanHandle(string color);
void Print(string message);
}
The managed extensibility framework (MEF) makes it easy for me to accomplish what I’m trying to do. The factory contains a static list of IPrinters and is populated by the code in the static constructor using MEF. Unfortunately, MEF does not support static imports. I did not use MEF to automatically compose the PrinterFactory because I think it’s unnecessary to new up instances of each printer when only one is going to be returned, hence the static list and constructor.
public class PrinterFactory
{
private static IList<IPrinter> Printers { get; set; }
static PrinterFactory()
{
var catalog = new DirectoryCatalog(Environment.CurrentDirectory, "Demo.*");
var container = new CompositionContainer(catalog);
Printers = container.GetExportedValues<IPrinter>().ToList();
}
public IPrinter Create(string color)
{
foreach (IPrinter printer in Printers)
{
if (printer.CanHandle(color))
return printer;
}
return null;
}
}
I’m using the DirectoryCatalog to find the assemblies. The core library and the libraries that contain the implementations will normally be copied to the same bin directory since they are both referenced by the console application. My console application can now create a PrinterFactory to create an IPrinter.
static void Main(string[] args)
{
var factory = new PrinterFactory();
RedPrinter printer = factory.Create("red") as RedPrinter;
printer.Print("hello world");
}
This is all I would need to do if my core library was targeting .NET 4.0. However, if my core library needs to target an older version of the framework (2.0, 3.0, 3.5), I cannot use MEF without adding an extra dependency. At this point, I need to fall back to loading assemblies and using the Activator to create an instance of each IPrinter. The factory’s static constructor now looks like:
static PrinterFactory()
{
string[] paths = Directory.GetFiles(Environment.CurrentDirectory, "Demo.*.dll");
foreach (string path in paths)
Assembly.LoadFrom(path);
Printers = AppDomain.CurrentDomain
.GetAssemblies()
.SelectMany(x => x.GetTypes())
.Where(x => typeof(IPrinter).IsAssignableFrom(x) && !x.IsAbstract && !x.IsInterface)
.Select(x => (IPrinter)Activator.CreateInstance(x))
.ToList();
}
Disabling Visual Studio extension’s menu item
I’ve created a Visual Studio extension with a new menu item that appears under the Tools menu. However, when there are no solutions open, I want to disable the menu item.
When I first create a Visual Studio package, an Initialize method is auto-generated:
protected override void Initialize()
{
Trace.WriteLine (string.Format(CultureInfo.CurrentCulture, "Entering Initialize() of: {0}", this.ToString()));
base.Initialize();
// Add our command handlers for menu (commands must exist in the .vsct file)
OleMenuCommandService mcs = GetService(typeof(IMenuCommandService)) as OleMenuCommandService;
if ( null != mcs )
{
// Create the command for the menu item.
CommandID menuCommandID = new CommandID(GuidList.guidMyVSPackageCmdSet, (int)PkgCmdIDList.cmdidMyCommand);
MenuCommand menuItem = new MenuCommand(MenuItemCallback, menuCommandID );
mcs.AddCommand( menuItem );
}
}
MenuCommand does not have any events that I can hook into, but changing the type to OleMenuCommand exposes the BeforeQueryStatus event that allows me to execute code before the status of the command is checked.
OleMenuCommand menuItem = new OleMenuCommand(MenuItemCallback, menuCommandID );
mcs.AddCommand( menuItem );
menuItem.BeforeQueryStatus += (sender, evt) =>
{
// I don't need this next line since this is a lambda.
// But I just wanted to show that sender is the OleMenuCommand.
OleMenuCommand item = (OleMenuCommand) sender;
DTE service = (DTE) this.GetService(typeof (DTE));
Solution solution = service.Solution;
item.Enabled = solution.IsOpen;
};
However, this does not work as expected. When I first launch Visual Studio without a solution loaded, the menu item is still enabled. What I found was that the Initialize method is not called until the first time you click on your menu item. This code works after I’ve clicked on my menu item once, but I want the menu item disabled by default when Visual Studio first opens.
To disable the menu item by default, I’ll need to add a command flag. In the .vsct file that is auto-generated, I can add a command flag to the button item to have it disabled by default.
<Button guid="guidMyVSPackageCmdSet" id="cmdidMyCommand" priority="0x0100" type="Button"> <Parent guid="guidMyVSPackageCmdSet" id="MyMenuGroup" /> <Icon guid="guidImages" id="bmpPic1" /> <CommandFlag>DefaultDisabled</CommandFlag> <Strings> <CommandName>cmdidMyCommand</CommandName> <ButtonText>My Menu Item</ButtonText> </Strings> </Button>
This does successfully disable the menu item by default when Visual Studio is launched without a solution. However, since the button is now disabled, I cannot click on it, even after a solution is open. Since the package isn’t loaded until the first time I click on the menu item, the package is never loaded and the Initialize method is never called.
To fix this problem, I’ll need the package to automatically load once a solution is opened in Visual Studio, regardless if I’ve clicked on the menu item or not. I need to add an attribute to my package class:
[ProvideAutoLoad("f1536ef8-92ec-443c-9ed7-fdadf150da82")]
This attribute forces my package to load when a specific UI context is available. In this case, the GUID here represents when a solution exists. There are a number of other UI context GUIDs available under the VSConstants enum.
My extension now works as expected. When I launch Visual Studio without a solution open, the menu item is disabled. Once I open a solution and click on the the Tools menu, the BeforeQueryStatus event is triggered and my menu item is enabled.
Promoting better coding practices in a corporate environment: A lost cause?
Testability seems to be a misunderstood concept. I regularly see this type of code in reviews:
public class MyBusinessClass
{
private MyDataAccess _dataAccess;
public MyBusinessClass(bool isTest)
{
if (isTest)
_dataAccess = new MockDataAccess();
else
_dataAccess = new ProductionDataAccess();
}
}
I often see code that violates the single responsibility principle and developers have a difficult time testing the component in question. To me, having code that is difficult to test should raise a red flag. But I see many developers continue and write the same code, thinking that this is just a side effect of unit testing.
People tend to gravitate towards the simplest working solution at the time for the code they are working on. Normally that is a great thing. We want to keep things simple. However, I don’t believe simple “hacks” are correct solution at any time. As the project grows, the maintainability issues that these simple hacks introduce are compounded. I honestly can’t tell if people can’t see the problems they are about to run into, or they simply don’t care.
I often suggest using an inversion of control container to help manage dependencies, but people seem to reject using a container due to the fact that it adds complexity. I completely understand that a container may not be appropriate in all situations, but when you start writing static classes/factories to manage dependencies, people should reconsider.
How do I help promote better coding practices? Is it possible to change this culture? In a corporate environment with project deadlines, pressure from management, etc…, should people care about these topics?
Perhaps I’m just naive and I want to believe that people care, but I see conflicting opinions everyday. I have been attempting to give feedback, but have been met with much resistance. I am fully aware of the Dunning-Kruger effect, and strive to understand a topic before speaking about it. I realize that there isn’t one right way to do things and I absolutely respect other people’s opinion. However, I fully believe that there are ways to do things that introduce unnecessary pain and pressure points.
Is it worth trying to educate and encourage? In my current situation, I feel powerless to instigate real change. Is this a lost cause and I should just accept the fact that this will always be a problem in a corporate environment that is focused on product delivery rather than quality? What can I do to get things started?
Dynamically composing predicates
Typically when I’m using LINQ to filter collections, my conditions aren’t very complex and usually contain a single boolean condition. For example, if I wanted to filter a collection of WorkItems, I’ll use the Where extension method:
workItems.Where(x => x.Status == Status.Done);
I’ve come across a scenario where I needed to chain multiple “OR” expressions. It’s easy to chain multiple “OR” expressions during compile time:
workItems.Where(x => x.Status == Status.Done || x.Status == Status.Processing);
However, this is difficult to do if the conditions are determined at runtime. In an application, I’m asking the user to select from a list of statuses. They may select one or more statuses.

Since I still work a lot with stored procedures, I’ll typically use dynamic SQL to generate a WHERE clause if these status were stored in a database. But with a collection, this isn’t easy to do without some help.
After looking around, I stumbled across the PredicateBuilder class that ships as part of LINQKit.
The PredicateBuilder allows me to easily chain multiple “AND” and “OR” conditions together at runtime. I can append an “OR” condition to the predicate if the respective checkbox is checked:
var predicate = PredicateBuilder.False<WorkItem>();
if (cbIdle.Checked)
predicate = predicate.Or(x => x.Status == Status.Idle);
if (cbProcessing.Checked)
predicate = predicate.Or(x => x.Status == Status.Processing);
if (cbDone.Checked)
predicate = predicate.Or(x => x.Status == Status.Done);
workItems.Where(predicate.Compile());
The PredicateBuilder also allows me to nest predicates and create complex conditions. For example, if I wanted to create a predicate that is equivalent to the following:
workItems.Where(x =>
x.Status == Status.Done &&
(x.Description.Contains("report") || x.Description.Contains("summary"))
);
… I can create two predicates and append them together.
var description = PredicateBuilder.False<WorkItem>();
description = description.Or(x => x.Description.Contains("report"));
description = description.Or(x => x.Description.Contains("summary"));
var condition = PredicateBuilder.True<WorkItem>();
condition = condition.And(x => x.Status == Status.Done);
condition = condition.And(description);
workItems.Where(condition.Compile());
Custom model binding
The default model binder in ASP.NET MVC does a good job of binding items that follow a certain naming convention. But if you’re using third party controls, you typically do not have control over the HTML they generate. One of the third party controls I’m using in my project allows a user to select a date range. At a minimum, the generated HTML looks something like this:
<p>
Start date:
<input type="text" name="StartMonth" />
<input type="text" name="StartDay" />
<input type="text" name="StartYear" />
</p>
<p>
End date:
<input type="text" name="EndMonth" />
<input type="text" name="EndDay" />
<input type="text" name="EndYear" />
</p>
I want to bind the results to my DateRange model:
public class DateRange
{
public DateTime Start { get; set; }
public DateTime End { get; set; }
}
ASP.NET MVC provides an extension point to do custom model binding. We simply need to implement IModelBinder and register it in global.asax.cs in the Application_Start method:
public class DateRangeModelBinder : IModelBinder
{
public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
int startMonth = this.GetValue(bindingContext, "StartMonth");
int startDay = this.GetValue(bindingContext, "StartDay");
int startYear = this.GetValue(bindingContext, "StartYear");
int endMonth = this.GetValue(bindingContext, "EndMonth");
int endDay = this.GetValue(bindingContext, "EndDay");
int endYear = this.GetValue(bindingContext, "EndYear");
return new DateRange
{
Start = new DateTime(startYear, startMonth, startDay),
End = new DateTime(endYear, endMonth, endDay)
};
}
private int GetValue(ModelBindingContext context, string name)
{
return (int)context
.ValueProvider
.GetValue(name)
.ConvertTo(typeof(int));
}
}
ModelBinders.Binders.Add(typeof(DateRange), new DateRangeModelBinder());
I’m omitting error checking in the custom model binder for this post, but normally you’ll want to catch format exceptions, add model state errors, etc…. At this point, I can add a DateRange as the action method parameter and get the expected result.
[HttpPost]
public ActionResult Index(DateRange input)
{
return View();
}
If I want to keep my form submission as simple as this, everything works perfectly. However, the model binding above does not work if I create a new model with DateRange as a property.
public class Incoming
{
public string Name { get; set; }
public DateRange DateRange { get; set; }
}
In the Incoming model, I’ve added a Name property and a DateRange property. My form submission now includes other information in addition to a date range. When I swap out the DateRange parameter in my action method with the Incoming class, the model binding does not work as expected. If I put a breakpoint inside the action method and inspect the input, I’ll see that the date range is null.
The problem seems to indicate that the DefaultModelBinder in ASP.NET MVC does not check the type, but rather matches on names. In this case, my property is named “DateRange” and since my HTML is generated by a third party control, I can’t change the names. What I need to do is override the DefaultModelBinder and replace it with a custom one that checks property types.
public class CustomModelBinder : DefaultModelBinder
{
protected override void BindProperty(ControllerContext controllerContext, ModelBindingContext bindingContext, PropertyDescriptor propertyDescriptor)
{
if (propertyDescriptor.PropertyType != typeof(DateRange))
{
base.BindProperty(controllerContext, bindingContext, propertyDescriptor);
return;
}
DateRangeModelBinder modelBinder = new DateRangeModelBinder();
object dateProperty = modelBinder.BindModel(controllerContext, bindingContext);
propertyDescriptor.SetValue(bindingContext.Model, dateProperty);
}
}
I’ve created a custom model binder and have overridden the BindProperty method. If the property is a type of DateRange, I’ll use the DateRangeModelBinder and manually map the property on the model. I also need to register it in global.asax.cs in the Application_Start method:
ModelBinders.Binders.DefaultBinder = new CustomModelBinder();
At this point, I’ve set the default model binder to the one I’ve created and everything works as expected. But this only works for the date range control. If I had multiple third party controls, I don’t want to pollute the CustomModelBinder with multiple if statements. To make it easier to add additional model binders in the future, I’ve created an interface:
public interface IPropertyBinder
{
bool ShouldHandle(Type propertyType);
void Bind(ControllerContext controllerContext, ModelBindingContext bindingContext, PropertyDescriptor propertyDescriptor);
}
The implementation for the date range control looks like this:
public class DateRangePropertyBinder : IPropertyBinder
{
public bool ShouldHandle(Type propertyType)
{
return propertyType == typeof(DateRange);
}
public void Bind(ControllerContext controllerContext, ModelBindingContext bindingContext, PropertyDescriptor propertyDescriptor)
{
DateRangeModelBinder modelBinder = new DateRangeModelBinder();
object dateProperty = modelBinder.BindModel(controllerContext, bindingContext);
propertyDescriptor.SetValue(bindingContext.Model, dateProperty);
}
}
The ShouldHandle method will check to see if it’s the type expected. The Bind method will use DateRangeModelBinder and manually set the property. To use this new interface, I’ll need to update the CustomModelBinder.
public class CustomModelBinder : DefaultModelBinder
{
private readonly IPropertyBinder[] propertyBinders;
public CustomModelBinder(IPropertyBinder[] propertyBinders)
{
this.propertyBinders = propertyBinders;
}
protected override void BindProperty(ControllerContext controllerContext, ModelBindingContext bindingContext, PropertyDescriptor propertyDescriptor)
{
foreach (IPropertyBinder binder in propertyBinders)
{
if (binder.ShouldHandle(propertyDescriptor.PropertyType))
{
binder.Bind(controllerContext, bindingContext, propertyDescriptor);
return;
}
}
base.BindProperty(controllerContext, bindingContext, propertyDescriptor);
}
}
I’ve updated the BindProperty method to loop over the list of property binders. The list of property binders is typically supplied by an inversion of control container. Again, I’ll need to update the Application_Start method in global.asax.cs.
CustomModelBinder modelBinder = container.Resolve<CustomModelBinder>(); ModelBinders.Binders.DefaultBinder = modelBinder;
To add additional model binders in the future, I simply need to implement the IPropertyBinder interface and make sure that it’s registered with my inversion of control container.
ASP.NET MVC Areas
One of the new additions in ASP.NET MVC 2 was areas, which allows me to organize my projects into smaller sections. The ASP.NET MVC project that I’ve been working on has grown to a point where splitting it into smaller sections made sense. After adding areas, I noticed a few quirks.

Here I’ve created a new area called “About” with a HomeController. I’ve also added a HomeController to my root controllers folder. At this point, I’d expect to be able to visit “/Home” and “/About/Home”, each displaying their own pages. However, I received an error whenever I try to visit “/Home”.
Multiple types were found that match the controller named 'Home'. This can happen if the route that services this request ('{controller}/{action}/{id}') does not specify namespaces to search for a controller that matches the request. If this is the case, register this route by calling an overload of the 'MapRoute' method that takes a 'namespaces' parameter.
The request for 'Home' has found the following matching controllers:
MvcDemo.Controllers.HomeController
MvcDemo.Areas.About.Controllers.HomeController
Turns out that I can’t have duplicate controller names across my areas. To remedy this issue, I needed to make an adjustment to the default route found in global.asax.cs.
routes.MapRoute(
"Default",
"{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional },
new string[] { "MvcDemo.Controllers" }
);
Adding a fourth argument to the MapRoute method informs the handler that it should look in the specified namespace first. If it can’t find an appropriate controller in that namespace, fall back to the default behavior. After adding that, I was able to successfully visit “/Home” and “/About/Home” and hit the correct controllers.

Here I’ve created an additional controller in the About area named ContactMeController. I was able to successfully visit “/About/ContactMe” and have it display the correct page. When I visit “/ContactMe”, I expected to receive a HTTP 404 back. However, I received a different error.
The view 'Index' or its master was not found or no view engine supports the searched locations. The following locations were searched: ~/Views/ContactMe/Index.aspx ~/Views/ContactMe/Index.ascx ~/Views/Shared/Index.aspx ~/Views/Shared/Index.ascx ~/Views/ContactMe/Index.cshtml ~/Views/ContactMe/Index.vbhtml ~/Views/Shared/Index.cshtml ~/Views/Shared/Index.vbhtml
This indicates that the handler found a controller, but the ViewResult could not find a view. This is the same scenario we encountered above with the two HomeControllers since the handler by default does not respect area namespaces. The namespace I added earlier was a namespace that has priority, but does not constrain it to that namespace. At this point, I want the controllers in the root controllers folder to be restricted to their namespace.
Route route = routes.MapRoute(
"Default",
"{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional },
new string[] { "MvcDemo.Controllers.*" }
);
route.DataTokens["UseNamespaceFallback"] = false;
I’ve updated the namespace to include everything in that namespace and below. I’ve added an extra DataToken “UseNamespaceFallback” and set it to false. This extra DataToken indicates that the handler should not fall back to other namespaces in the project if it cannot find a controller in the specified namespace. Now I can visit “/ContactMe” and receive back the expected HTTP 404. At the same time, I can visit “/About/ContactMe” and have it return the correct page.
WCF Data Services and maxReceivedMessageSize
We have a WCF Data Service (Astoria) that uses most of the default configuration settings. Every once in a while, a client would receive the following exception:
System.Data.Services.Client.DataServiceRequestException: An error occurred while processing this request. ---> System.Data.Services.Client.DataServiceClientException: BadRequest
This exception only occurs when the client sends a large message. The default message size in WCF is 65536. Since we’re using a WCF Data Service and not a normal WCF Service, adding a WCF Data Service (.svc) to the project does not auto-generate the service/binding information in the config. To increase the message size, I needed to manually enter the service/binding information:
<system.serviceModel>
<services>
<service name="MyNamespace.MyService">
<endpoint bindingConfiguration="msgSize" address="" binding="webHttpBinding" contract="System.Data.Services.IRequestHandler" />
</service>
</services>
<bindings>
<webHttpBinding>
<!-- 2097152 = 2 MB-->
<binding name="msgSize" maxReceivedMessageSize="2097152" maxBufferSize="2097152" />
</webHttpBinding>
</bindings>
</system.serviceModel>
The service name is the class (.svc) that inherits from System.Data.Services.DataService<T>.
Strongly typed ASP.NET session
Following my previous post on strongly typed dictionaries, I wanted to use the same DictionaryAdapter component for ASP.NET sessions. However, the ASP.NET session object does not implement IDictionary. Since the session object acts like a dictionary, we’ll need to wrap it. Using the session adapter found here, we can now utilize the DictionaryAdapter component to create strongly typed implementations.
DictionaryAdapterFactory factory = new DictionaryAdapterFactory(); IHomeSession session = factory.GetAdapter<IHomeSession>(new SessionDictionary(HttpContext.Current.Session));
Each of my controllers only use a subset of the information stored in session. To avoid creating a “master” interface that contains all the different keys, I can create multiple interfaces that only map values that the controller needs.
public interface IHomeSession
{
string First { get; set; }
string Last { get; set; }
int? Age { get; set; }
}
public interface IAccountSession
{
string First { get; set; }
string Last { get; set; }
string Middle { get; set; }
int? Age { get; set; }
}
public interface IOtherSession
{
[Key("OtherFirstName")]
string First { get; set; }
[Key("OtherLastName")]
string Last { get; set; }
}
Each of these interfaces are injected into different controllers. The Home controller would be injected with IHomeSession and so forth. Since the DictionaryAdapter component maps the property name to keys, the First string property on IHomeSession would map to the same value as the First string property on IAccountSession. Although IOtherSession also has a First string property, I’m using the Key attribute to denote that it should map to the key OtherFirstName.
public class HomeController : Controller
{
private readonly IHomeSession session;
public HomeController(IHomeSession session)
{
this.session = session;
}
public ActionResult Index(string first, string last, int age)
{
this.session.First = first;
this.session.Last = last;
this.session.Age = age;
return View();
}
}
I can register each interface separately:
container.Register
(
Component
.For<IHomeSession>()
.UsingFactoryMethod(x =>
{
DictionaryAdapterFactory factory = new DictionaryAdapterFactory();
return factory.GetAdapter<IHomeSession>(new SessionDictionary(HttpContext.Current.Session));
})
);
… but this quickly becomes a friction point if we have multiple interfaces and would like to create additional interfaces in the future. Instead, we can register the DictionaryAdapterFactory as a singleton and get a list of all the interfaces that match a certain convention. We’ll loop through and register each one individually.
container.Register
(
Component
.For<DictionaryAdapterFactory>()
.LifeStyle.Singleton
);
IEnumerable<Type> sessions =
Assembly
.GetExecutingAssembly()
.GetTypes()
.Where(x => x.IsInterface && x.Name.EndsWith("Session"));
foreach (Type session in sessions)
{
Type sessionTemp = session;
container.Register
(
Component
.For(session)
.UsingFactoryMethod(x =>
{
DictionaryAdapterFactory factory = x.Resolve<DictionaryAdapterFactory>();
return factory.GetAdapter<object>(sessionTemp, new SessionDictionary(HttpContext.Current.Session));
})
.LifeStyle.PerWebRequest
);
}
At this point, we can create additional interfaces that match the current convention and the container will automatically register and inject them.
Using Web Forms user controls in an ASP.NET MVC project
We have an existing ASP.NET Web Forms project that we’re in the process of slowly converting to ASP.NET MVC. We do not have the manpower to simply rewrite the entire website from scratch, so one of our goals is to slowly convert the website piece by piece. This means that the existing Web Forms project will need to coexist with emerging MVC project.
In the current Web Forms project, we have a number of user controls that are used on all our pages. In order to maintain backwards compatibility with our Web Forms pages, we couldn’t rewrite the controls as MVC helpers without having to duplicate code.
I created this helper that allows us to reuse Web Forms user controls on views:
public static class UserControlHelper
{
public static HtmlString RenderControl<T>(this HtmlHelper helper, string path)
where T : UserControl
{
return RenderControl<T>(helper, path, null);
}
public static HtmlString RenderControl<T>(this HtmlHelper helper, string path, Action<T> action)
where T : UserControl
{
Page page = new Page();
T control = (T)page.LoadControl(path);
page.Controls.Add(control);
if (action != null)
action(control);
using (StringWriter sw = new StringWriter())
{
HttpContext.Current.Server.Execute(page, sw, false);
return new HtmlString(sw.ToString());
}
}
}
By instantiating a Page and adding the user control to it, we can render the result as a string. To use the helper on a view, we can call it like this:
@(Html.RenderControl<MyCustomControl>("~/Test/MyCustomControl.ascx"))
The entire method call needs to be surrounded with parentheses, otherwise the angle brackets will confuse the Razor view engine. If the user control has properties that need to be set, we can call the method overload and pass it an expression:
@(Html.RenderControl<MyCustomControl>("~/Test/MyCustomControl.ascx", x => x.Name = "Malvin"))
@(Html.RenderControl<MyCustomControl>("~/Test/MyCustomControl.ascx", x =>
{
x.Name = "Malvin";
x.Age = 25;
}))
Razor declarative helpers
I’m currently converting an old ASP.NET MVC 2 project to MVC 3. In my MVC 2 project, I created HTML helpers to generate small bits of HTML.
public static HtmlString SampleHtmlHelper(this HtmlHelper helper, string input)
{
string result = "<div>";
result += "<p>Current time: " + DateTime.Today.ToShortDateString() + "</p>";
result += "<p>Input: " + input + "</p>";
result += "</div>";
return new HtmlString(result);
}
These helper classes would reside in a Helpers folder that I create.

To use the helper, I’d call it in a view like this:
<h2>Demo</h2>
@Html.SampleHtmlHelper("hello world")]
ASP.NET MVC 3 with the Razor view engine introduces a new way of creating declarative helpers that allows me to take advantage of the Razor syntax instead of appending strings together.
@helper SampleHelper(string input)
{
<div>
<p>Current date: @DateTime.Today.ToShortDateString()</p>
<p>Input: @input</p>
</div>
}
This helper would be placed in a view page in the App_Code folder.

I can treat each helper as a static method based on the view page name:
<h2>Demo</h2>
@Demo.SampleHelper("hello world")
I can convert most of my older HTML helpers to declarative helpers, but I’ve come across cases where I needed to continue creating helpers in code. I find that helpers that contain a lot of logic do not fit well with the Razor syntax.
public static HtmlString SampleHtmlHelper<TModel, TReturn>(this HtmlHelper<TModel> helper, Expression<Func<TModel, TReturn>> expression)
where TModel : class
{
MemberExpression memberExpression = GetMemberExpression(expression);
string name = memberExpression == null ? null : memberExpression.Member.Name;
Func<TModel, TReturn> function = expression.Compile();
TReturn value = function(helper.ViewData.Model);
string result = "<div>";
result += "<p>" + name + ": " + value + "</p>";
result += "</div>";
return new HtmlString(result);
}
Being able to leverage the Razor syntax for helpers is a real bonus. I don’t see a need to use partial views anymore. When I needed to decide whether to use a helper or a partial view, it would be determined by how much markup I needed to generate. I would typically use a HTML helper if the amount of markup wasn’t a burden or if it contained logic. But with the new declarative helpers, this isn’t an issue anymore. Are there any benefits that a partial view has over declarative helpers?