StructureMap: Part 4 - Scanning


Index

So far I’ve shown enough to build a working DI system. By registering concrete types for your abstractions you can fully configure the container. However it’s unlikely to have escaped your notice that doing so is a not inconsequential amount of work in anything but small systems. StructureMap provides a solution to this in the form of auto registration.

Auto registration takes advantage of the fact that the structure of most types that we wish to register in a container follows certain patterns or conventions. By taking advantage of these conventions we can locate and register types with the container without having to specify them individually. Further if we adhere to the conventions for new types they will be registered automatically without any additional work. This reduces our configuration to specification of the conventions and individual registration for those few types for which the conventions are inapplicable.

We can start with one of the simplest and most common conventions. There are a wide variety of instances that adhere to the simple pattern of having a concrete class that implements an interface that shares the same name with the addition of the standard .NET I prefix. This abstraction breaks the coupling between the implementation and anything that may use it but for most cases there is not a need to have multiple implementations of the abstraction. They are generally transient instances and any state they carry does not last between uses. A stateless service is a typical example.

Consider an assembly that contains many services, among them ExampleService which implements IExampleService. Using auto registration we can locate and register into the StructureMap container all of these services that adhere to our convention. The code to do so will look like:

ObjectFactory.Initialize(initialise =>
    {
        initialise.Scan(scan =>
            {
                scan.TheCallingAssembly();
                scan.WithDefaultConventions();
            });
    });

This code utilises the type scanner to perform registration. The Scan method takes a delegate (of type Action<IAssemblyScanner>) for which we can supply a lambda. In the lambda we do two things. The first is instruct the scanner where it should be scanning. In this case we specify the assembly in which this code is located by invoking the method TheCallingAssembly. The then tell StructureMap to apply its default conventions. The StructureMap default conventions are conveniently equivalent to the convention described above.

This method may be used to register large numbers of types and is probably the most common usage of the scanner. It will cover most cases but the scanner is capable of significantly more than this. Let’s consider another convention. We have some kind of plug-in system where all plug-ins must implement a common interface. We’d like to register all of our plug-ins with the container but we won’t (and likely can’t) have the close correspondence between the name of the plug-in interface and that of the types that implement it. We can use another convention in the scanner to handle this for us. We can add a call to AddAllTypesOf<T> to our scanner. This will cause it to register any class that implements the specified generic type. For an interface of type IPlugin this would look like:

ObjectFactory.Initialize(initialise =>
    {
        initialise.Scan(scan =>
            {
                scan.TheCallingAssembly();
                scan.WithDefaultConventions();
                scan.AddAllTypesOf<IPlugin>();
            });
    });

(We have kept the call to WithDefaultConventions here but it is not necessary to register the IPlugin implementations)

This supports the case where IPlugin is non-generic. We may also encounter situations where we wish to register anything that implements a generic interface. Let’s assume that for some (probably crazy) reason our system also has a plugin interface IPlugin<T> for which we wish to register any implementations. StructureMap provides inbuilt support for this scenario using the ConnectImplementationsToTypesClosing method.

Before I show the code, a quick diversion through the basics of open and closed generic types. The type IPlugin<T> is an open generic type for which the type parameter is not specified. We cannot (for all practical purposes) have an instance of this type as it is incomplete. We can obtain the type itself using typeof(IPlugin<>). If we want an instance we must get a closed type for which the type parameters have been specified. IPlugin<int> would be an example and we may treat this type for the most part as we would a non-generic type. We can through reflection determine the open generic type for a closed type and create a closed type from an open type. This is annoying and fortunately StructureMap handles it all for us. (We can also have partially closed types, but that’s outside the scope of this post)

The code to register all the concrete classes that implement (and therefore close) our generic interface looks like:

ObjectFactory.Initialize(initialise =>
    {
        initialise.Scan(scan =>
            {
                scan.TheCallingAssembly();
                scan.ConnectImplementationsToTypesClosing(typeof(IPlugin<>));
            });
    });

All of these examples scan the assembly in which the code itself resides. This is the most common option but there are cases where scanning of other assemblies may be desirable. This includes cases where you wish to register instances from an assembly you do not control and where you may wish to scan a directory for plug-in or extension assemblies that are unknown at compilation time. To handle these cases StructureMap provides a number of options other that TheCallingAssembly for specifying where it should scan. These include:

  • AssembliesFromApplicationBaseDirectory scans every assembly in (surprisingly) the applications base directory. It has an overload that supports providing a filter to exclude assemblies if desired.
  • AssembliesFromPath scans every assembly in the directory with the specified path. It also has an overload for providing a filter.
  • Assembly takes an individual assembly to be scanned (as either an instance of the Assembly type or by name)
  • AssemblyContainingType supports determining the assembly to be scanned by specification of a type within the assembly (as either a type parameter or instance of the Type class)

It is also possible to control how the scanner treats types within an assembly using Exclude or Include rules. Exclude rules allow patterns to be specified that will prevent any matching type from being registered. Any type matching one or more exclude rules will be ignored by the scanner:

  • Exclude takes a filter delegate than allows individual types to be excluded from the scanner.
  • ExcludeNamespace takes a string defining a namespace. The scanner will exclude all types in this namespace.
  • ExcludeNamespaceContainingType has a type parameter. Any types sharing the namespace of the specified type will be excluded.
  • ExcludeType takes a generic parameter. The specified type for this parameter will be excluded.

Include rules support patterns that all types to be registered must adhere to. A type must match at least one include rule to be registered:

  • Include takes a filter delegate. Any type matching this filter will be included.
  • IncludeNamespace takes a string defining a namespace. Any type in this namespace is included.
  • IncludeNamespaceContainingType has a type parameter. Any type sharing a namespace with this type will be included.

Inside a single Scan invocation you should generally use either all Exclude or all Include statements.

Scanning allows us to significantly simplify the configuration of the container. If you have a system with more than one assembly you may be thinking that you will need to specify the assemblies to scan or invoke StructureMap configuration manually inside each assembly. StructureMap provides a better mechanism for doing so in the form of Registries which will be the subject of the next post in this series.

author: Colin David Scott | posted @ Saturday, July 03, 2010 11:43 AM | Feedback (0)

StructureMap: Part 3 – Constructing the Concrete Type


Index

Now that we can control the lifecycle of an instance it’s worth considering how those instances are constructed. In the code shown so far the parameter-less Use method is responsible for specifying the concrete type. Using this overload will cause StructureMap to create instances using the type constructor. This will cover many scenarios but there will be cases where you will need more control over how instances are constructed. For these scenarios StructureMap provides a number of overloads for Use.

The simplest scenario is that we wish the container to always supply an instance we already have. This is almost illegally simple:

var existingInstance = new ExistingInstance();
ObjectFactory.Initialize(initialise =>
	{
		initialise.For<IExistingInstance>().Use(existingInstance);
	});

The container will now return the specified instance. This has an implication on the lifecycle. As we’ve specified the instance to return we get Singleton behaviour. To demonstrate the code:

var firstExistingInstance = ObjectFactory.GetInstance<IExistingInstance>();
var secondExistingInstance = ObjectFactory.GetInstance<IExistingInstance>();

Console.WriteLine(string.Format("Existing instances are the same: {0}", ReferenceEquals(firstExistingInstance, secondExistingInstance)));

Produces the output:

 image

This is unlike the default behaviour when we specify the type not the instance where StructureMap will create a new instance for every call to GetInstance<T>. It is therefore important that any instance registered in the container in this fashion be threadsafe when used in a multi-threaded environment.

Being able to use an existing instance is helpful but we will also have situations where we need to specify the mechanism used to construct a new instance. This allows us to use lifecycles other than Singleton as well as having control over instance construction. For this purpose StructureMap provides two overloads to Use that take Func delegates. By supplying a lambda or method to one of these overloads we can specify the code to be used to generate instances.

The simpler method takes a Func<T> (where T is the plugin type). Its usage is straightforward:

initialise.For<IDynamicItem>().Use(() => new DynamicItem());

We can also specify constructor parameters:

initialise.For<IDynamicItem>().Use(() => new DynamicItem("Some Parameter"));

Or a method that matches the Func<T> signature:

initialise.For<IDynamicItem>().Use(DynamicItemFactory.CreateItem);

In short we can do all the normal things that are supported for Func<T> arguments to a method.

The more complex method takes a Func<IContext, T> and is useful for scenarios where the construction process needs to consider the context in which the instance is being created. This is useful for advanced scenarios that will be described later in this series. However I will note here that IContext supports GetInstance<T> making this the overload to use when you are manually constructing an instance that has dependencies you wish to obtain from the container. For example:

initialise.For<IDependentDynamicItem>().Use(context => new DependentDynamicItem(context.GetInstance<IDynamicItem>()));

Before this part of the series ends it’s worth considering the behaviour of the standard parameter-less Use method we’d been using prior to this article. This overload causes StructureMap to use a constructor on the type to create instances. If there is only a single constructor then it is obvious which constructor to use. However things are not always this simple. There are a few things to consider in how StructureMap selects the constructor to use.

The first thing to note is that StructureMap will only consider public constructors. A type with no public constructors cannot be handled and will result in a StructureMapException. If you need to use a type with no public constructors with StructureMap then you must use the Use overloads discussed in this post.

Of the public constructors StructureMap will pick that which has the most arguments. This is done on the general assumption that the constructor with the most arguments will supply the greatest number of dependencies to the instance. In the event that there are multiple constructors that match this criteria StructureMap will pick the first it encounters. In such scenarios it is probably best to eliminate the excess constructors in order to ensure certainty and reduce confusion. Where this is not possible (for instance if the type is supplied by an external library) taking over construction using a Use overload as described above should be seriously considered. The alternative is to rely on behaviour that is liable to change if StructureMap, the external library are updated.

Now that we can control both the construction and lifecycle of instances the next post in this series will describe how we can make most of the configuration we’ve done so far unnecessary.

author: Colin David Scott | posted @ Friday, June 18, 2010 12:53 AM | Feedback (0)

StructureMap: Part 2 – Instance Lifecycles


Index

So far I’ve shown how to do basic registration. This will let the container know of the type so that it will try to create it. This registration gives us the defaults that StructureMap assumes unless it is told otherwise. These defaults are reasonable for most types but they’re not always applicable. This post describes some of the options StructureMap provides for controlling how the container manages the lifecycle of instances.

By default StructureMap constructs instances transiently. Each time the instance is requested from the container a new instance is constructed and returned to the controller. We can demonstrate this with the following code snippet:

ObjectFactory.Initialize(initialise =>
	{
		initialise.For<ITransientService>().Use<TransientService>();
	});

var firstTransientService = ObjectFactory.GetInstance<ITransientService>();
var secondTransientService = ObjectFactory.GetInstance<ITransientService>();

Console.WriteLine(string.Format("Transient instances are the same: {0}",
	ReferenceEquals(firstTransientService, secondTransientService)));

When we run this we get the following output:

image

In general this is not an issue. Most types managed by StructureMap do not need to carry state between operations, and the construction of lightweight transient objects in .NET is very cheap. Unfortunately this doesn’t apply to all types. There are circumstances where we need to maintain state potentially across many operations. Some types are expensive to construct such that for performance reasons it simply isn’t feasible to keep creating new instances. Types may also wrap limited resources such that we may not be able to construct new instances if existing instances already exist. For this reason StructureMap supports lifecycles.

The lifecycle controls when new instances are created and how StructureMap maintains references to the. The transient default specifies that a new instance is created per request and that StructureMap will not track the instance. Additionally StructureMap provides the following lifecycles:

  • Singleton
  • Thread Local
  • Unique Per Request
  • Http Context
  • Http Session
  • Hybrid
  • Hybrid Session

The Singleton lifecycle is a mechanism to provide Gang of Four Singleton semantics to an instance. Specifying this lifecycle causes StructureMap to create only a single instance of the concrete type. It holds a reference to this instance and provides it whenever that type is requested. We can specify this lifecycle by using the Singleton method in the fluent interface thusly:

initialise.For<ISingletonService>().Singleton().Use<SingletonService>();

If we now add to our example code the following:

var firstSingletonService = ObjectFactory.GetInstance<ISingletonService>();
var secondSingletonService = ObjectFactory.GetInstance<ISingletonService>();

Console.WriteLine(string.Format("Singleton instances are the same: {0}",
    ReferenceEquals(firstSingletonService, secondSingletonService)));

We get the output:

image

The Singleton lifecycle is effective for when global state must be managed or an instance is expensive to create. It is also useful to manage cases where a limited set of resources must be controlled.

Implementing Singleton manually is generally a bad thing. Manual Singletons result in tight coupling and are difficult to test. The Singleton lifecycle gets around this problem by passing the problem of ensuring that there is only a single instance over to the container. The type marked with the Singleton lifecycle may be implemented as a standard instance type. It may have dependencies to be satisfied as can any other type managed by the container. The only consideration is that the type must be threadsafe when used in multi-threaded environments as the same instance will be provided on all threads.

Sometimes we wish to manage instances on a per-thread basis rather than globally and for this reason StructureMap provides the Thread Local lifecycle. This lifecycle creates and maintains an instance for each thread that requests the plugin type. Two requests on the same thread will receive the same instance whereas requests on different threads will be given different instances. This is often useful for tracking execution state within a thread or for managing expensive resources that are not threadsafe.

Using thread local storage in web applications is potentially problematic due to the way ASP.NET handles threads. StructureMap therefore provides lifecycles that use ASP.NET constructs to store data. These are Http Context and Http Session which quite naturally use the ASP.NET Context and Session storage respectively. Using these lifecycles gives instances the lifecycle of the associated ASP.NET storage. You may apply Http Context using the HttpContextScoped method. For Http Session there is no helper method but you can apply the scope by calling the LifecycleIs method (for which the Singleton and HttpContextScoped methods are convenient wrappers) as shown:

initialise.For<IHttpSessionService>().LifecycleIs(new HttpSessionLifecycle()).Use<HttpSessionService>();

The standard restrictions for using these ASP.NET constructs apply. In particular care should be taken in what is places in the Session.

In many circumstances code need to be agnostic as to what kind of environment that it runs in. Using Http Context and Http Session ties the code to ASP.NET preventing its use in client or service applications. This scenario is covered by the Hybrid and Hybrid Session lifecycles. These will use the ASP.NET Context or Session (respectively) if it is available. Otherwise they will use thread local storage. Using these lifecycles allows code to run in many environments but instances must adhere to the restrictions of both types of scope. Failure to adhere to the restrictions of both thread local storage and ASP.NET Context (or Session) means that the code will fail in one environment even if it works correctly in the other. The Hybrid lifecycle may be applied using the HybridHttpOrThreadLocalStorage method. Hybrid Session is applied using the code:

initialise.For<IHybridSessionService>().LifecycleIs(new HybridSessionLifecycle()).Use<HybridSessionService>();

Of the built in lifecycles this leaves Unique Per Request. The behaviour of this lifecycle is somewhat more subtle. To illustrate it take this (somewhat contrived) class that requires two instances of ITransientService.

public interface IRequiresMultipleTransientServices
{
	void MultipleTransientDoStuff();
}

public class RequiresMultipleTransientServices : IRequiresMultipleTransientServices
{
	private readonly ITransientService _firstTransientService;
	private readonly ITransientService _secondTransientService;

	public RequiresMultipleTransientServices(ITransientService firstTransientService,
		ITransientService secondTransientService)
	{
		_firstTransientService = firstTransientService;
		_secondTransientService = secondTransientService;
	}

	public void MultipleTransientDoStuff()
	{
		Console.WriteLine(string.Format("Service instances are the same: {0}",
			ReferenceEquals(_firstTransientService, _secondTransientService)));
	}
}

If we run this we get the output:

image

What we see here is that in the context of a single call to ObjectFactory.GetInstance<T> the container constructs the ITransientService instance only once. Generally this behaviour is desirable or at least neutral. However we may have a case where we need all the instances to be different, for instance if they carry state that could get corrupted if used through different references that are unaware of each other. For this scenario we have the Unique Per Request lifecycle, which can be applied with:

initialise.For<IUniquePerRequestService>().LifecycleIs(new UniquePerRequestLifecycle()).Use<UniquePerRequestService>();

We can demonstrate the effect with:

public interface IRequiresMultipleUniquePerRequestServices
{
	void MultipleUniquePerRequestDoStuff();
}

public class RequiresMultipleUniquePerRequestServices : IRequiresMultipleUniquePerRequestServices
{
	private readonly IUniquePerRequestService _firstUniquePerRequestService;
	private readonly IUniquePerRequestService _secondUniquePerRequestService;

	public RequiresMultipleUniquePerRequestServices(IUniquePerRequestService firstUniquePerRequestService,
		IUniquePerRequestService secondUniquePerRequestService)
	{
		_firstUniquePerRequestService = firstUniquePerRequestService;
		_secondUniquePerRequestService = secondUniquePerRequestService;
	}

	public void MultipleUniquePerRequestDoStuff()
	{
		Console.WriteLine(string.Format("Unique per request service instances are the same: {0}",
			ReferenceEquals(_firstUniquePerRequestService, _secondUniquePerRequestService)));
	}

Giving the output:

image

By applying the Unique Per Request Lifecycle we now get a new instance of the dependency everywhere its requested.

Although a single instance requesting multiple undifferentiated instances of the same dependency is unlikely and generally unhelpful it is not at all unusual that the same dependency will appear multiple times within the same dependency tree for a complex dependency graph. The separate scenario where a type wants multiple distinct concrete dependencies that implement the same plugin type will be discussed later in this series.

Now that we can control the lifecycle of an instance the next post in this series will show how we can control how instances are created.

author: Colin David Scott | posted @ Sunday, June 13, 2010 1:22 PM | Feedback (0)

StructureMap: Part 1 – The Basics


Index

Let’s start at the beginning which is allegedly a very good place to start. Before StructureMap can construct any kind of concrete type for you it must be told what it should construct. StructureMap contains some powerful mechanisms to simplify this but to start with we’ll do it all manually. Later parts of this series will show how to apply conventions to configure StructureMap automatically.

Getting started with StructureMap is easy. First head over to http://structuremap.github.com/structuremap/ and download the latest release. Extract the StructureMap.dll assembly and add a reference to it in your project. You’re now ready to start using StructureMap in your application.

Pro tip: Remember to unblock the assembly if you’re on a version of windows that has this “feature” or you’ll get some very strange errors at runtime.

We can initialise StructureMap using the ObjectFactory class. This static class provides the primary interface for interacting with the StructureMap container. We can configure the container using either the Initialize or Configure methods. These methods provide very similar functionality. The primary difference is that Initialize will reset any existing configuration whereas Configure is additive to existing configuration (Initialize also provides some functions only relevant to the initial configuration of the container). In most cases Initialize is the appropriate method to call at the start of your application. Configure can then be used if you need to add to the configuration elsewhere.

So how does this work? Let’s take a simple example where I have some service SimpleService. In order to allow types that depend on this service to be independent of it’s implementation I create an abstraction in the form of the interface ISimpleService. These types look like this:

public interface ISimpleService
{
   
void DoStuff();
}

public class SimpleService : ISimpleService
{
   
public void DoStuff()
    {
       
Console.WriteLine("Doing stuff");
    }
}


If I was to request ISimpleService from StructureMap now I’d get a StructureMapException telling me there was no default instance registered for that type. This can be fixed with a call to Initialize like so:

ObjectFactory.Initialize(initialise =>
   
{
        initialise.
For<ISimpleService>().Use<SimpleService>();
    });

This is a Nested Closer, a term you don’t need to entirely understand in order to use it. What is important to know is that StructureMap evaluates the lambda passed to this method in order to configure the container. StructureMap provides a Fluent Interface for configuration that is both very readable and highly expressive. Let’s examine this simple example.

We start by calling the For<T> method on initialise. The type parameter specifies the plugin type that we’re dealing with. The plugin type is the type we deal with when requesting instances from the container and is generally an abstraction (interface or abstract class).

The return type of the For<T> method provides a number of methods for configuring what we are registering. This is typical of fluent interfaces (which are outside the scope of this discussion). In this case we are using the simple no-parameter Use<T> method. The type parameter specifies what concrete class is to be supplied when someone requests the plugin type. Here we are specifying that SimpleService will be provided when ISimpleService is requested. Due to the magic of generics when we specify the configuration in this was we will get a compile time error if the concrete type does not implement or derive from the plugin type.

This is sufficient code to start requesting things, or at least instances of ISimpleService, from the container. This may be accomplished using the GetInstance<T> method:

var simpleService = ObjectFactory.GetInstance<ISimpleService>();

simpleService.
DoStuff();

The simpleService variable will be of type ISimpleService. Running this code will print he message Doing stuff to the console. By itself this isn’t particularly useful but it is a building block on top of which we can get more sophisticated and useful functionality. Consider:

public interface IMoreComplexService
{
   
void DoMoreComplexStuff();
}

public class MoreComplexService : IMoreComplexService
{
   
private readonly ISimpleService _simpleService;

   
public MoreComplexService(ISimpleService simpleService)
    {
       
_simpleService = simpleService;
    }

    public void DoMoreComplexStuff()
    {
       
Console.WriteLine("Start complex stuff");

       
_simpleService.DoStuff();

       
Console.WriteLine("End complex stuff");
    }
}


Here we have a more complex service that uses ISimpleService in order to perform its function. Rather than creating a concrete instance of its dependency through a traditional mechanism such as new or a factory method the MoreComplexService class requires it as a constructor parameter (I’ve omitted for clarity the null check production code should have). When creating an instance of MoreComplexService some implementation of ISimpleService must be provided. One of the nicest and most powerful features of StructureMap is that it can do this for us. This feature is called auto-wiring and it greatly simplifies composing your application. To make this all work all we need to do is tell StructureMap about the new IMoreComplexService, like so:

ObjectFactory .Initialize(initialise =>
   
{
        initialise.
For<ISimpleService>().Use<SimpleService>();
        initialise.
For<IMoreComplexService>().Use<MoreComplexService>();
    });


With this configuration StructureMap has everything it needs to supply instances of IMoreComplexService. We can retrieve and use an instance of IMoreComplexService as shown:

var moreComplexService = ObjectFactory.GetInstance<IMoreComplexService>();

moreComplexService.
DoMoreComplexStuff();


When IMoreComplexService is requested from the container the configuration indicates that MoreComplexService is the concrete type to be supplied. However this type does not have a no-argument constructor meaning that more information is required to create an instance. Using reflection the container can determine that what is required is an instance of ISimpleService, a type StructureMap knows how to construct. It will the perform auto-wiring, automatically creating the necessary dependency and supplying (or wiring) them where required.

The MoreComplexService here is using Constructor Injection where the necessary dependencies are injected via the constructor. This is generally the preferred way to inject dependencies as it ensures that they are available when the instance is used. There are however some exceptions to this which will be discussed later in this series.

Provided that there are no circular dependencies the container is capable of wiring dependencies to any level. These elements are enough to fulfil many common applications for dependency injection. However most production applications will need more control over the creation and lifecycle of some instances. Additionally having to specify each instance individually is verbose and somewhat error prone. Rectifying these concerns will be the subject of the next few posts in this series.

author: Colin David Scott | posted @ Saturday, June 12, 2010 11:26 PM | Feedback (1)

StructureMap: Part 0 - Introduction


Dependency Injection is a shamefully under-utilised practice in .NET development. There’s really little excuse for this as there are a number of serviceable frameworks available. These include Castle Windsor (http://www.castleproject.org/container/index.html), Spring.NET (http://www.springframework.net/) or even Unity (http://unity.codeplex.com/) if you’re stuck at a Microsoft-only shop. However my personal preference is StructureMap (http://structuremap.github.com/structuremap/) which has a number of features that I like:

  • Simple deployment There’s a single StructureMap assembly to be referenced and it’s rare to encounter a situation where you need multiple incompatible versions.
  • Minimally intrusive StructureMap doesn’t require the use of attributes, marker interfaces or base classes to work with your types.
  • No XML XML configuration for dependency injection is difficult to write, maintain and debug. StructureMap can support XML where necessary but most configuration occurs through code.
  • Convention based configuration StructureMap includes by default powerful mechanisms to apply convention based configuration to your DI setup. Once these conventions are established you can largely forget it’s there.
  • Stable and mature StructureMap has been around longer than any other .NET DI framework and has the stability and maturity you’d expect from such longevity.
  • Well thought out API The StructureMap API has been heavily refactored over time to produce something powerful, readable and highly expressive.

This is the introduction to a series of posts I’m writing to introduce StructureMap. My driver for this is to get a new team up to speed with it for a current project but I’m writing for a more general audience. I hope someone find it useful (or at all).

Index

author: Colin David Scott | posted @ Saturday, June 12, 2010 11:25 PM | Feedback (2)

ReSharper and MvcContrib Portable Areas


I’ve recently been looking at MvcContrib portable areas after a colleague suggested they could be the solution to providing an application a composite UI. While looking at this I noticed that ReSharper 5 had a few issues, primarily in views. This is not entirely unexpected as splitting a site across multiple projects is hardly standard MVC behaviour (although it’s pretty much exactly what we want in this scenario). I made a comment on this on Twitter and got a response from a Jetbrains Technical Evangelist. This post is to describe the behaviour I’m seeing in more detail that Twitter allows.

The main issues are with views, as can be seen below. This is a screenshot of the MvcContrib Portable Areas sample, specifically the view in the Login portable area. Unsurprisingly ReSharper can’t find the master page which is in a different project. More surprisingly it can’t find the generic ViewPage class and therefore doesn’t appear to be able to work out the page base class. This means that Intellisense is unaware of the Html property and therefore isn’t working for any of the MVC code in the view.

image

Additionally (and less importantly) in the controllers the views are not detected and ReSharper prompts to create them.

image

This all seems to be the result of doing things in an unusual way and it seems unreasonable to expect tools to cover every possible contingency. Apart from these glitches the latest ReSharper 5 EAP builds seem a big improvement.

author: Colin David Scott | posted @ Tuesday, April 06, 2010 9:50 AM | Feedback (1)

On the naming of classes with similar purposes in different contexts


It’s not uncommon in an application to have different representations of the same concept in different contexts. For instance you may have a concept encoded as a domain object and also as a type in a message contract. In this case you will generally want to use the same name in each context. However this has the disadvantage that the class name is now somewhat ambiguous.

In such cases there will likely be at least one place in the code where you will need to refer to both contexts. This necessitates a mechanism for distinguishing between the types from each context. The result that you will need to qualify type names. You may chose to include the namespace of one context and qualify the types of the other context. In practice I find this problematic because it requires the application of a convention that is not obvious and of which tooling is unaware. This may result in inconsistency in qualification between code files which may be confusing.

To alleviate this concern you can choose to qualify all types from both contexts. I find this preferable as it removes a potential source of ambiguity. Unfortunately some tools will attempt to be helpful and remove the qualifications. The removal of qualifications is unlikely to be consistent between code files which means this assistance must be undone. This is a small but noticeable cost when editing these files.

I tend to consider having to use qualification of types within a single solution to be a failure of type naming. In some cases this will be because a name is being incorrectly carried between contexts. When dealing with our example of a domain and a message context it will generally be the case that there shouldn’t be a one-to-one correspondence between domain and message types. The existence of a Product domain type does not necessarily imply that there should be a Product message type. In this case message types that better align to the purpose of a message context may be more suitable. We may chose to have messages such as UpdateProduct or ProductCreated which are more relevant to the business purposes to which messages may be put (in this case a command and a notification message respectively).

Using names more suitable to their context will significantly reduce the duplication in names but there will always be exceptions. For instance in most systems an Address is a value object that is relatively similar regardless of context. As addresses are rarely entities in their own right it is likely that they will be a component of other types in a context rather than being used directly. As such there is not really the opportunity to assign business specific names in each context.

My solution to this is to have an agreed suffix for type names within each context. This allows any type from a context to have a name that is clear and unambiguous without qualification. This suffix is generally redundant when the full type name including namespace is considered. In this usage I feel that the redundancy is acceptable due to the improvements achieved in actually using the types. This convention is also more obvious that picking which context is to be qualified or qualifying all contexts, and is significantly more likely to be followed consistently in a team environment.

author: Colin David Scott | posted @ Tuesday, March 16, 2010 9:18 PM | Feedback (0)

Upfront Database Design Is Evil and Foolish


A practice that I occasionally encounter is having the database to be used by a system entirely “designed” upfront before development starts. This practice implies that the data structure an application requires may be anticipated before the code is developed. Practical experience shows this view to be at best naive.

Attempting to fully anticipate the needs of a system upfront is an exercise in futility. Any business system complex enough to be worth considering as a project will have facets that only become apparent as the system is constructed. Additionally as a development team works with a problem domain they will generally gain additional insight into the nature of the problem and the required solution. Feeding this knowledge back into the system design will result in a more effective solution that will be better suited to the business use. The system will also likely be cheaper to build and maintain as it will more cleanly express the business problems and will not require the kinds of excessive and redundant logic a poorly suited model necessitates.

Attempting to design the database upfront will almost certainly miss key information and produce a sub-optimal representation of the business concern. As this is generally apparent when a developer is required to work with an upfront design I generally see it in two scenarios. The first is when it is requested by a client who believes it to be a necessary or expected process. It is the job of development teams in this scenario to educate clients who cannot and should not be expected to be experts in software development.

I also see it with developers who are unfamiliar with the development of anything but very small systems. I have done this myself when I was a junior developer but this practice is not acceptable in anyone who aspires to be a senior developers. Senior developers must recognise the boundaries of their experience and understand when the knowledge and practices that they apply in the domains they are familiar with no longer apply. In my experience it is significantly more likely to be a problem when developers who only work at small scales attempt to work on larger systems. Larger systems are much less forgiving of loose practices and techniques that are often (wrongly) considered unnecessary at the lower end become mandatory at the higher end.

My preferred approach with databases at this time is to utilise automatic generation capabilities to produce the relevant schema from the application. Any ORM worth using should have such a capability. This approach focuses on the needs of the application and relies on the underlying technology to make it all work. This is efficient in terms of developer productivity. Where relevant it remains possible to optimise for specific cases but this can be done only where necessary.

author: Colin David Scott | posted @ Tuesday, March 16, 2010 9:17 PM | Feedback (0)

Locating your project tooling


Many development projects rely on tools in addition to standard integrated development environments. How these tools are managed can have a significant impact on the maintainability of the project. Problems can occur when different development environments are using different versions of tools, or when tools are assumed available but not present in some environments. This can also be an issue between different branches in the same environment when tools or tool versions change.

It’s unfortunately common for developers to rely on tools being installed in an environment. This makes changing the tool version problematic as the change must be coordinated with all team members. If there is shared build infrastructure then changes may potentially impact multiple projects and can introduce undesirable coupling between otherwise unrelated development efforts.

What is required is a solution that allows projects to maintain their own versions of tools and that provides a mechanism for distributing changes to all environments. In development this solution is source control. Placing tools in the source control repository causes updated versions of tools to be automatically distributed when a new version is pulled from the repository.

Placing tools in the repository solves the problem of distribution, but will not necessarily resolve all the potential issues. In particular if the repository contains a single instance of the tools shared between branches then changes made for one branch may adversely impact other branches. This is obviously undesirable and defeats the point of branching. This is resolved by having the tools be part of each branch, allowing versioning to be conducted for specific branches without affecting others.

This relies on tools that can run from any location without requiring installation. Most development tools I’ve encountered will work in this fashion, but there are exceptions. This should be a factor in tool selection. Where a tool cannot work in this fashion there are in most cases alternatives that can. Over the life of a project the ability to manage tools effectively will generally outweigh the incremental gains from using a tool that cannot be managed in source control. This will of course not always apply, as in some scenarios there are no suitable alternatives. In these scenarios careful management and coordination will be required. Where possible projects relying on such tools should not share development infrastructure so that they are not subject to issues introduced through changes to other projects.

There are some tools that it is reasonable to assume are installed. This is generally true of tools that are part of the platform. For instance it is reasonable to assume that the .NET Framework SDK is installed on a machine used for development tasks. When making such assumptions it is necessary to consider that the available tools can vary between versions of the platform. This is generally not an issue with the .NET Framework which is consistent across OS versions (assuming the full version is installed) but can be an issue for system utilities.

The same kind of versioning issues can apply to libraries referenced by projects. Outside assemblies that form part of the .NET Framework each branch should contain copies of all the assemblies required to build the system. It is desirable but not necessary that this allow the system to run, although it should be possible to execute all the unit tests without having custom software installed.

author: Colin David Scott | posted @ Wednesday, February 17, 2010 11:42 PM | Feedback (0)

Boy scouts on amphetamines


Disclaimer: No boy scouts were harmed in the production of this post

The Boy Scout Rule is in my opinion a highly valuable mechanism for ensuring that a code base remains effective over time. The Boy Scouts of America have the rule “Leave the campground cleaner than you found it.”* Applying this to the code as it is maintained provides an efficient mechanism for ensuring code quality. The marginal effort required is relatively low as you are already working with it and hence the effort to understand the purpose and structure of the code is already required.

At this point I want you to imagine a boy scout cleaning a camp site while under the influence of significant quantities of amphetamines. Such a hypothetical boy scout is going to get their camp site very, very clean. And probably clean other camp sites as well even if, for instance, there are still people sleeping in the tents being packed away. Now that you’ve imagined all of this, you have some idea of the reputation I have for editing existing codebases.**

Continuous cleaning of a codebase is beneficial over the lifetime of a project but it must also be recognised that there are costs involved. In particular the additional changes complicate source control activities and require additional communications within the development team. There is also the inherent risk involved in any change to a software systen, The existence of these costs doesn’t mean that you should not improve the code as you go. It does however mean that you should be measured in how you do so.

When joining a project I will often go through a lot of the code and “tidy” it. This may involve cosmetic changes such as applying consistent formatting and removing unused namespaces. It may also involve restructuring of logic like reducing the level of nesting and extracting methods. I find this helpful in getting a handle on the structure of a system. Sometimes I may touch over half the files in a system. What I have learnt however is that many of these changes should be undone using the magic of source control. Generally I will keep a few key modifications related to the features on which I am working and discard the rest. This is not wasted effort as I have gained a better understanding of the system from the changes. Additionally many of the changes are made with automated tools and hence can be repeated efficiently later.

By distributing the changes over time the costs and risks involved are dramatically reduced. This is a good thing, even if it does go against my fundamental nature. My challenge now is not to block my inner boy scout but to ensure that he stays in rehab.

* I have no idea if this is true in Australia as during my brief time in the scouts I was The Worst Scout in the Entire World™

** And I do it all without drugs. Apart from my hopeless caffeine addiction.

author: Colin David Scott | posted @ Sunday, December 27, 2009 2:03 PM | Feedback (0)