random .NET and web development musings

I simultaneously work on multiple web projects, and have a back catalogue of scores of sites that could need my attention at any time.

I always run my sites locally in a fully fledged IIS site (rather than using Cassini) which means each site needs its own hostname.

Until recently I had been managing this with my hosts file, simply adding a new line:

127.0.0.1  mysite.dev

for each site. However last week I reached breaking point as my hosts file was about 3 pages long.

Enter Velvet. Velvet adds wildcard support to your hosts file by acting as a simple DNS server that you can run stand alone or (preferably) as a windows service.

I have now reduced 3 pages of hosts entries into a two lines:

127.0.0.1  *.dev
127.0.0.1  *.*.dev

actually theres a few others, such as wildcard mappings to my colleagues machines:

192.168.0.2  *.jim
192.168.0.2  *.*.jim
192.168.0.3  *.bob
192.168.0.3  *.*.bob

This means I now rarely ever need to touch my hosts file, at least not for standard day-to-day project work :)

Ultra time saving win.

Check out the project on github.

Feature suggestions welcome!

We all suck at estimating, regardless of how experienced we are. This is a fact that you should accept. Most of us are either ignorant to this or in denial. There are many ways we try to hide our inadequacies, mostly revolving around mathematical transformations of the form:

E’ = mE + c

I.E. make an arbitrary estimate (E), multiply it by some amount (m) and add a bit (c).

I’m not denying that there is some sense to this, you can spend considerable time and effort refining your favourite m value by tracking your velocity, having regular retrospectives and reflective analyses etc.

This method alone however is ignorant to significant mental “quirks” which affect the way you think and reason.

The effects I am talking about are:

  • The “halo” effect
  • Framing effects
  • Overconfidence
  • Attribute Substitution
  • Base-rate neglect
  • Anchoring

The “halo” effect

The “halo” effect is defined as “the influence of a global evaluation on evaluations of individual attributes”. What this means in the realm of software development estimation is that you are likely to estimate the individual parts of a project with a bias towards how you feel about the overall project.

If you’ve formed an opinion that overall the project will be easy, all your estimates for the component parts are likely to be lower than if you viewed the project as difficult (known as the “devil” effect).

Pro Tips:

  • Ignore prejudices
  • Judge tasks independantly
  • Don’t “do the easy ones first”

Framing effects

Framing effects refers to the way our mind perceives data differently depending on how it is presented. For example, food which is “90% fat free” sounds much better than food described as “10% fat”.
When estimating tasks, we are very likely to bias our judgement based on how the requirements are presented. For example, requirements which are positively worded/presented and which sound easy/appealing are much more likely to receive lower estimates.

Pro Tips:

  • Has the way the requirements been worded affected your interpretation?
  • Are your judgements of a specific problem being clouded by its surroundings?

Overconfidence and Substitution

Little weight is given to the quality or quantity of evidence when we form a subjective confidence in our opinions. Instead, our confidence depends largely on the quality of the story we can tell ourselves about the situation. What this means is that we are very likely to be confident in an estimate if we have convinced ourselves that we know what we’re talking about. This may sound obvious, however the devil lies in the detail. Do we really know what we are talking about? Our brains do not like doubt and uncertainty, we are much happier answering questions positively rather than negatively. When estimating a task, we are very likely to jump to a conclusion (underestimate) if the task is familiar to us. How many times have you said “oh yeah that’s simple, it will take X hours” without _really_ thinking it through? This is known as the mere-exposure effect.

This is where another problem creeps in, attribute substitution. When our brains are faced with a complex question, our sub-conscious often substitutes the problem for a more familiar, easier problem. This often happens without us realising. This leads to misunderstandings of the problem domain and therefore inaccurate estimates.

Pro Tips:

  • Ask yourself why you are confident
  • Are you biasing because of familiarity?
  • Have you really understood the problem?

Base Rate Neglect

Base rate neglect or base rate bias is an error which occurs when assessing the probability of something and failing to take into account the prior probability. I use the term here partly in the strictest sense (as defined by Wikipedia above) and partly in a more general sense.
When we estimate tasks, we often fail to account for the “surrounding” or “prior” cost of the task, such as the complicated merge that will be required after the change, or the reliance on the third party delivering on time, the API documentation being adequate etc.

Pro Tips:

  • Consider all the implications
  • What assumptions have you made? – Are they sensible? Really?
  • Refuse to estimate unknowns

Anchoring

Anchoring is an effect that causes you to bias your estimate based on estimates you’ve already seen or produced. If two developers are discussing an estimate and the first says “10 days”, the second developer is more likely to produce a number closer to “10 days” than if they hadn’t spoken previously. This is one of the main benefits of using planning poker. By avoiding the influence of others until you have produced your estimates, you are much more likely to get a broader range of estimate values.

You may think broader means worse, but this is not necessarily the case. If one dev thinks a task is “1 day” but another thinks its “10 days” – you’ve identified a problem. Either you have a huge skill disparity, or there has been a fundamental misunderstanding by one or both parties!

Pro tips:

  • Try to view each estimate in isolation, dont let previous numbers skew future ones
  • Don’t confer with other estimators until you all have your own value, then justify why they are different

Summary

When producing estimates be aware of biases and make an conscious effort to spot when you might be making them. Being aware that you are likely to be biased is the first step in producing more accurate estimates, actually counteracting the biases in practice can be much harder ;)

Remember:

  • Estimate alone at first
  • Get 2nd (or more) opinions on estimates, but be careful not to cause framing or anchoring biases
  • Make a conscious effort to not misinterpret a requirement based on its wording
  • Be sure you’ve not jumped to conclusions because of familiarity of the problem
  • Review the estimates you produced last. Are they biased based on the estimates your produced first?
  • Estimate each task in isolation. Dont let your opinions of other tasks or the whole project effect individual parts

If you are interested in learning more about the psychology of decision making and biases and how you can make personal improvements (not just in development estimation) then I highly recommend you get your hands on a copy of the following:

When implementing custom exceptions in .NET, especially if you’re writing a library that others are going to use, always implement the deserialization constructor:

MyException (SerializationInfo info, StreamingContext context) : base(info, context)

Not doing so will cause others to hate you when your exceptions cause further SerializationExceptions.

just do it.

If you make a table 100% width:

table {
    width: 100%
}

then you’ll find that the cells within it will arrange themselves so they have a width proportional their respective content lengths. However, sometimes you might want to have cell be as narrow as possible, and fit itself down to its contents, and let the others auto width themselves.

One options is to give the cell in question a fixed width, but this isnt a flexible solution if the width needs to vary.

Step up the following:

table {
    width 100%;
}
table td.narrow {
    width: 1px;
    white-space: nowrap;
}

the width on the cell will make it behave like the min-width property, it will be at least 1px wide, larger content will cause it to expand. Brilliant! Then add a cheeky nowrap to prevent it from wrapping at whitespace and you’re away!

Aceness

Annoyed to death that Twitter have swapped the column order round on their site so the content is on the right, I’ve made an extension for Chrome that fixes it.

Here’s how to do it.

Make a folder somewhere, and inside it create a file called “manifest.json”. Put this inside it:

{
	"name": "Fix Twitter Columns Order"
	, "version": "0.1"
	, "description": "Switches the Twitter columns around so content is on the left"
	, "content_scripts": [
		{
			"matches": ["https://twitter.com/*", "http://twitter.com/*"]
			, "css": ["style.css"]
		}
	]
}

Then create a file called “style.css” and put this inside it:

.content-main
{
	float: left !important;
}

.dashboard
{
	float: right !important;
}

And there we go!

Goto Chrome -> Tools -> Extensions.

Tick “Developer Mode”, then click “Load unpacked extension” and navigate to the folder you created the json and css in.

Done! You can download the source here.

I wanted a simple way to manage canonical links in ASP.NET MVC.

It would have been nice to work these out automatically from the route tables, but for the project I am working on, its far too convoluted to be done easily, I’d rather maintain a fixed definition for each action.

Step up a custom `ActionFilterAttribute`:

[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)]
public sealed class CanonicalUrl : ActionFilterAttribute
{
	readonly string url;

	public CanonicalUrl(string url)
	{
		this.url = url;
	}

	public override void OnResultExecuting(ResultExecutingContext filterContext)
	{
		var uri = filterContext.RequestContext.HttpContext.Request.Url;
		var fullyQualifiedUrl = (uri.Scheme + "://" + uri.Host + this.url).ToLowerInvariant();

		foreach (var key in filterContext.RouteData.Values.Keys)
			fullyQualifiedUrl = fullyQualifiedUrl.Replace("{" + key.ToLowerInvariant() + "}",
															filterContext.RouteData.Values[key].ToString());

		filterContext.Controller.ViewData["CanonicalUrl"] = fullyQualifiedUrl;
		filterContext.HttpContext.Response.Headers.Add("link", "<" + fullyQualifiedUrl + ">; rel=\"canonical\"");

		base.OnResultExecuting(filterContext);
	}
}

You can then decorate your actions like this:

[CanonicalUrl("/show/{name}")]
[AcceptVerbs(HttpVerbs.Get)]
public ActionResult Show(string name)

Make sure you stick the link element in your page’s head:

<% if(ViewData["CanonicalUrl"] != null){ %>
	<link rel="canonical" href="<%: ViewData["CanonicalUrl"] %>" />
<%} %>

If you want to cast an Enumerable’s inner type, you can use LINQ:

var casted = myEnumerable.Cast<int>();

But what when you only know the inner type (int) at runtime?

The easiest way is the following reflection magic:

public static IEnumerable Cast(this IEnumerable self, Type innerType)
{
	var methodInfo = typeof (Enumerable).GetMethod("Cast");
	var genericMethod = methodInfo.MakeGenericMethod(innerType);
	return genericMethod.Invoke(null, new [] {self}) as IEnumerable;
}

I’ve used two approaches to “embedding” the ascx views, one thats quite simple, and one thats a bit more complicated and needs quite a lot of explanation as to why I’m doing it that way.

The easiest way to do it is to embed the ascx file, and access it with a Custom VirtualPathProvider.

This approach however suffers several drawbacks.

The first problem comes at dev time. You have to rebuild every time you change the ascx. This might not be a problem for you, but in large projects it can add several seconds delay to every change you make, which for someone whos trying to be productive, can be very annoying.

The easiest solution to this is to modify the custom VirtualPathProvider above so that it is aware whether it is in dev or production mode. I do this with the debug attribute in the web config:

public bool AreInDevMode
{
	get
	{
		var section = ConfigurationManager.GetSection("system.web/compilation") as CompilationSection;
		return section.Debug;
	}
}

Then, when you’re in dev mode, check the file system before checking for the embedded resource. This will perhaps involve some path hackery, but generally I’m ok with this because the path conventions in my projects are consistent.

The second problem with this method is that the view is essentially embedded as a string, the text that makes up the view ascx. This means the view has to be compiled at runtime. This has two issues:

a) its slow, especially when you have many views
b) you dont get build time compilation error checking.

So how do we solve this?

To compile the views, you need the ASP.NET Precompilation tool.

This will create a separate assembly for each compiled view. This is messy, so we can merge them together using the ASP.NET Merge tool.

Getting better, but you still have two assemblies, your main project code and the one with the views in. ILMerge to the rescue. However, before we do that I want to sort out the compiled view types.

If you open a precompiled view dll in reflector, you’ll find its rather messy and things aren’t named very nicely. For example, say your project has the following views:

/Plugins/PluginA/View-A.ascx
/Plugins/PluginB/View.ascx

You’ll end up with the following types:

plugins_plugina_view_a_ascx
plugins_pluginb_view_ascx

So, what I wan’t to do is put them back into the correct namespace. Unfortunately, because certain characters that are allowed in file paths are not allowed in namespaces, these chars get converted to underscores and you therefore can’t work out the namespace you need from the compiled type name alone. (e.g. you dont know if “path_to_some_view_ascx” was originally “path/to/some/view.ascx” or “path/to-some.view.ascx“)

Therefore I iterate over the file system and look for any .ascx, .aspx and .master files, turn their paths into their corresponding type names. I then have a lookup table of the type name and its original path.

THEN I can use Mono.Cecil to alter the type names.

so for the file:

/Plugins/PluginA/View.ascx

I calculate its type name:

plugins_plugina_view_ascx

and the name(space) I want it to have:

Plugins.PluginA.View

Do this for all the views and then I can ILMerge my two assemblies into one, nicely organised final package :D

So how do you then get MVC to render the view?

First you need to extend WebFormsViewEngine, and override:

protected override IView CreatePartialView(ControllerContext controllerContext, string partialPath) {
    return new WebFormView(partialPath, null);
}

protected override IView CreateView(ControllerContext controllerContext, string viewPath, string masterPath) {
    return new WebFormView(viewPath, masterPath);
}

So that it returns a custom View, which extends WebFormView and overrides Render:

public virtual void Render(ViewContext viewContext, TextWriter writer)

so that instead of creating the view using the BuildManager, it simply instantiates the type you worked out above.

If you followed any of that, well done!

In this series of posts I’m going to describe the techniques I use for supporting a plugin architecture in ASP.NET MVC.

What do I mean by plugin? Well, without going into the specific details of the system I’ve developed this for (it isnt important), a “plugin” is simply a bit of UI functionality I want to encapsulate into a package that I can reuse. These plugins typically include some codebehind, a view (ascx), some javascript and some css.

A typical plugin will look like this:

/plugins/exampleplugin/exampleplugin.cs
/plugins/exampleplugin/exampleplugin.css
/plugins/exampleplugin/exampleplugin.js
/plugins/exampleplugin/exampleplugin.ascx

When using a plugin, I want to just drop a dll in the bin (or reference it, whatever). I don’t want to have to manually add a script tag for the js, or a link for the css, or put the ascx in some views folder. I want everything to be included in a single file, and for everything to just work ™.

To achieve this I use several techniques:

  • Embed the css and javascript into the assembly as resources
  • Precompile the view into the assembly
  • Use a custom virtual path provider to make debug easier, and find the files at runtime.

These posts won’t go in to exact detail about how everything works and is wired together in my system (again, it isnt important and would only obscure the details). This isn’t a tutorial on how to build a plugin framework (that may be a future series of posts), but hopefully it will give you a few tips and tricks to try things out yourself.
There’s lots of bits I’ll gloss over, like optimisation :)

In this post I’ll cover embedding the css and js.

Embedding JS and CSS

Set the Build Action of the files (css, js) to “Embedded Resource” to embed them.

To get the files out of the assembly as string, you’ll need some code that looks like this:

static string GetResource(string key)
{
    var stream = this.GetType().Assembly.GetManifestResourceStream(key);
    using (var streamReader = new StreamReader(stream))
        return streamReader.ReadToEnd();
}

One thing to note is the naming rules that apply when you embed a file. Namespace sections that begin with a number get the number prefixed with an underscores, slashes get converted to dots and dashes to underscores. For example:

/assets/css/960-grid.css
becomes
.assets.css._960_grid.css

You’ll probably want some function that looks like this:

static string GetKey(string name)
{
    // folders beginning with a number have an _ prepended.
    name = Regex.Replace(name, @"/([0-9])", "/_$1");
    // turn / to . and - to _
    return name.Replace('/', '.').Replace('-', '_');
}

OK so that’s how we can get the css and js data out of the assembly, but then what to do with it?

Well, you’re probably going to have multiple plugins on a page, so you will have multiple css and js to include and you’ll want to bunch all this together. If you have some underlying plugin awareness mechanism, you could just pull the files you need:

var scripts = new StringBuilder();
var styles = new StringBuilder();
foreach (var plugin in page.Plugins)
{
    var key = plugin.GetType().FullName;
    key = GetKey(key);
    scripts.Append(GetResource(key + ".js"));
    styles.Append(GetResource(key + ".css"));
}

OR you could just get all the files in some “namespace”:

var scripts = new StringBuilder();
var styles = new StringBuilder();
var names = this.GetType().Assembly.GetManifestResourceNames();
foreach (var name in names)
{
    if(!name.StartsWith(".Plugins"))
        continue;

    if(name.EndsWith(".js"))
        scripts.Append(GetResource(name));
    else if(name.EndsWith(".css"))
        styles.Append(GetResource(name));
}

And there you go, you can then render these two strings into your page in a script and style tag :)

Some other ideas / Variations

If you don’t want to render the css and js directly into the page, you could use a script tag with a src pointing at a fake file. The fake file could be mapped to an IHttpHandler in the Web.config, or use an MVC route to a controller action.

For example, route: /assets/scripts/plugins.js to some code that does something similar to the above.

Want to see the most unhelpful code ever written?

Check out System.Transactions.TransactionManager.ValidateTimeout:

internal static TimeSpan ValidateTimeout(TimeSpan transactionTimeout)
{
    if (transactionTimeout < TimeSpan.Zero)
    {
        throw new ArgumentOutOfRangeException("transactionTimeout");
    }
    if (!(MaximumTimeout != TimeSpan.Zero) || ((transactionTimeout <= MaximumTimeout) && !(transactionTimeout == TimeSpan.Zero)))
    {
        return transactionTimeout;
    }
    return MaximumTimeout;
}

So thats saying, if you provide a timeout greater than the machine.config value, ignore it and use the machine.config one. Silently. No complaining, no warning.

To increase the machine.config timeout you need to add the following to machine.config (or adjust existing values if they are present):'

<system.transactions>
  <machineSettings maxTimeout="02:00:00"/>
  <defaultSettings timeout="02:00:00"/>
 </system.transactions>