<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://eduncan911.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Eric Duncan : MSpec, Computer Programming</title><link>http://eduncan911.com/archive/tags/MSpec/Computer+Programming/default.aspx</link><description>Tags: MSpec, Computer Programming</description><dc:language>en</dc:language><generator>CommunityServer 2.1 SP2 (Build: 61129.1)</generator><item><title>Managed Extensibility Framework (MEF) - Microsoft's Official Inversion of Control Container</title><link>http://eduncan911.com/blog/managed-extensibility-framework-mef-microsofts-official-inversion-of-control-container.aspx</link><pubDate>Tue, 16 Feb 2010 00:50:00 GMT</pubDate><guid isPermaLink="false">3cbf8099-f611-4197-a0f5-c5a9f8954971:6964</guid><dc:creator>Eric A. Duncan</dc:creator><slash:comments>5</slash:comments><comments>http://eduncan911.com/comments/6964.aspx</comments><wfw:commentRss>http://eduncan911.com/commentrss.aspx?PostID=6964</wfw:commentRss><description>&lt;p&gt;This new Microsoft feature in .NET Framework 4 is a programming model for reusing components, very similar to those Inversion of Control container frameworks out there that we all know and love (Castle Windsor, Structured Map, their own Unity from the Patterns and Practices team and etc).&amp;nbsp; Now, they have built their own to address the pain points of these frameworks called the Managed Extensibility Framework, or MEF for short.&lt;/p&gt; &lt;p&gt;I was pleasantly surprised this weekend when reading the February 02010's issue of MSDN Magazine.&amp;nbsp; Getting up-to-speed on some new features in .NET Framework 4, I saw the headline "&lt;a href="http://msdn.microsoft.com/en-us/magazine/ee291628.aspx" target="_blank"&gt;Building Composable Apps in .NET 4 with the Managed Extensibility Framework&lt;/a&gt;" by Glenn Block.&amp;nbsp; Yeah, it just rolls off your tongue eh?&amp;nbsp; So I decided I had a few minutes while waiting for the water to boil and scanned the article.&amp;nbsp; I am glad I did.&lt;/p&gt; &lt;p&gt;In this post, I will try to give a very brief overview on how to use MEF coming from a background of using other Inversion of Control (IoC) containers, including some of the gotchas that you must be aware of during the switch.&amp;nbsp; Yeah, you will want to make the switch - the switch away from those other bulky frameworks.&amp;nbsp; I, for one, am officially announcing my abandonment of Castle and Unity for all future projects.&amp;nbsp; Because once you add-in .NET 4's new data annotations for seriously improved validation, mixed with MEF, the only other 3rd party component I am left with is Castle's Logger abstraction - which I am hoping I can find a replacement for with .NET 4's new features.&lt;/p&gt; &lt;h2&gt;MEF Terminology&lt;/h2&gt; &lt;p&gt;First and fore-most for those of you already using an IoC container, it's time for a quick review on what MEF calls a few things and concepts.&amp;nbsp; Below is a table I whipped up to help compare the two terminologies (the MEF portions largely taken from Glenn's excellent article).&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;img style="border-bottom:0px;border-left:0px;display:inline;border-top:0px;border-right:0px;" title="2-15-2010 10-41-32 PM" border="0" alt="2-15-2010 10-41-32 PM" src="http://eduncan911.com/blog/thumbnail/ManagedExtensibilityFrameworkMicrosoftsO_A9C4/2152010104132PM_3.png" width="832" height="649"&gt; &lt;/p&gt; &lt;p&gt;Below is an image from Glenn's article that helps visualize the concepts above of MEF.&lt;/p&gt; &lt;p&gt;&lt;img style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" title="ee291628_Block_Fig1(en-us,MSDN_10)" border="0" alt="ee291628_Block_Fig1(en-us,MSDN_10)" src="http://eduncan911.com/blog/thumbnail/ManagedExtensibilityFrameworkMicrosoftsO_A9C4/ee291628_Block_Fig1enusMSDN_10.png" width="413" height="288"&gt; &lt;/p&gt; &lt;p&gt;You can see that the overall concept is called Composition.&amp;nbsp; A 'part' is the type or service you want to export.&amp;nbsp; The part (or parts) is marked for Export via Contracts (which are automatic).&amp;nbsp; And other parts that want to ask for another part can do so by Importing.&lt;/p&gt; &lt;h2&gt;Managed Extensibility Framework - Why they built it&lt;/h2&gt; &lt;p&gt;Glenn mentions in the article that they needed a way to compose of reusable types or components in the up coming Visual Studio 2010, Oslo, Acropolis and I am sure many more.&amp;nbsp; What is important to note is why they created one themselves, instead of using Unity or alike.&amp;nbsp; Glenn mentions some key points:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Third-party Extensibility (allowing vendors to generate plug-ins for Visual Studio, or your own application, with minimal work on your part now)  &lt;li&gt;Other frameworks were too heavyweight for a simple programming model.&amp;nbsp; &lt;li&gt;Or other frameworks required too much effort on the part of either the host or the extension developer. &lt;/li&gt;&lt;/ul&gt; &lt;p&gt;Those last two is what struck a cord with me, and got my attention.&amp;nbsp; Try to sit back and think about how you would allow your applications to be extended with Castle, StructureMap or even Unity.&amp;nbsp; That's a lot of work, a lot of 3rd party assemblies to wire up and configure properly.&amp;nbsp; Especially if you want runtime changes, which MEF supports out of the box with no configuration.&lt;/p&gt; &lt;p&gt;That last point is particularly interesting.&amp;nbsp; All too often I see a released developer framework or contrib project by a group of inspired individuals.&amp;nbsp; This is great and all, but those projects quickly grow to be a large project requiring documentation, support, and even refactorings for performance.&lt;/p&gt; &lt;p&gt;It got me thinking a lot about what I see wrong with Castle - only two things, it's learning curve and size.&amp;nbsp; While Unity was very well documented, it comes with some significant bloat and only what I can refer to as hoop-jumping.&amp;nbsp; The earlier versions of Unity violated Dependency Injection pricipals and concepts (no ctor injection!).&amp;nbsp; Perfect example of refactoring.&lt;/p&gt; &lt;p&gt;MEF really strives to resolve all of these issues, with some extremely simple programming models that I will show you below.&lt;/p&gt; &lt;p&gt;&lt;/p&gt; &lt;h2&gt;MEF Programming Models - Straight Attributed Declarations&lt;/h2&gt; &lt;p&gt;Another rip from Glenn's article.&amp;nbsp;&amp;nbsp; But he did it so well.&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;Developers consume MEF through a programming model.&amp;nbsp; A programming model provides a means to declare components as MEF parts.&amp;nbsp; Out of the box, MEF provides an attributed programming model, which will be the main focus of this article.&amp;nbsp; That model is just one of many possible programming models that MEF enables.&amp;nbsp; MEF's core API is completely agnostic to attributes.&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;Yep, you heard that right.&amp;nbsp; MEF supports Attributes - for out-of-the-box functionality.&amp;nbsp; No configuration, no setup, nothing.&amp;nbsp; This is so much easier than you are even thinking.&amp;nbsp; So much so, I feel guilty by writing all of this text.&amp;nbsp; Let's just show you how it's done now.&lt;/p&gt; &lt;h2&gt;The Blog "Hello World" Snippets&lt;/h2&gt; &lt;p&gt;As what seems to be an invasion, the common Hello World for websites these days &lt;a href="http://invalidlogic.com/2008/12/22/blogging-apps-are-the-new-hello-world/" target="_blank"&gt;are blogs&lt;/a&gt;.&amp;nbsp; So without further delay, here's some code snippets.&lt;/p&gt; &lt;p&gt;The post object&lt;/p&gt; &lt;p&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;
public partial class Post
{
	public Int32 PostId { get; set; }
	public String Title { get; set; }
	public String Description { get; set; }
	public String Body { get; set; }
	public Guid AuthorId { get; set; }
}

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;And the PostService that will service the post.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;
[Export(typeof(IPostService))]
public class PostService : IPostService
{
	[Import]
	public IPostRepository PostRepository { get; set; }

	public Post FetchById(Int32 postId)
	{
		return
			(from p in PostRepository.GetAll()
			 where p.PostId == postId
			 select p as Post).FirstOrDefault();
	}
}

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Please note that the above code is not production-code.&amp;nbsp; You should always provide proper cache, concurrency and disposable patterns.&amp;nbsp; This code has been cleaned up for easier reading.&lt;/p&gt;
&lt;p&gt;Notice that the PostService has been marked to be exportable, using a specific contract type for IPostService. Now, you do not have to specify the contract type or name. You can simply use [Export]. But remember, we do want to allow for simply extensibility in the future by plugging in different components to be served during composition.&amp;nbsp; How to do that?&amp;nbsp; Easy, just specify the interface type as the contract.&amp;nbsp; Now how easy was that?&lt;/p&gt;
&lt;p&gt;Also, notice that we have a dependency on IPostRepository. This is marked with the simple [Import] attribute.&amp;nbsp; It does exactly as you think.&amp;nbsp; MEF composes the first part that matches the contract for IPostRepository and supplies it &lt;/p&gt;
&lt;p&gt;Now, some will cry fowl here since I am not directly injecting IPostRepository, or not demanding it in the constructor. Yes, MEF fully supports constructor injection. But, there is a few gotchas you have to be aware of with MEF and constructor composition that I get into a little further down. There's also a new pattern I am designing, when mixed with .NET 4 and some nifty T4 templates I'm tinkering with. That's another article I'll write though. Check the comments, or leave a comment for more information on, "Managing BDD Contexts and Mocks Automatically with .NET 4, MEF, and T4 Templates." Nice. I just named my next blog post. &lt;/p&gt;
&lt;h2&gt;Constructor Dependency Injection - MEF Gotcha&lt;/h2&gt;
&lt;p&gt;As mentioned above, constructor injection is a bit tricky with MEF.&amp;nbsp; There are some rules to follow:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;MEF assumes all parameters are imports, making the import attribute unnecessary.&amp;nbsp; I leave it up to the reader to figure out how to get around this. 
&lt;li&gt;Recomposition is not supported on constructor parameters.&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;That last one is almost a deal breaker for me.&amp;nbsp; Recomposition is a feature of MEF that allows parts to automatically have their imports updated as new matching exports appear in the system.&amp;nbsp; Given, this isn't the case with most websites out there.&amp;nbsp; It's an issue for websites and applications that want to support dynamic (e.g. downloadable) plugins.&amp;nbsp; The plugins would overwrite, at runtime, certain contracts and therefore allow the parts to automatically be updated with the new plugin versions - all without an application restart!&lt;/p&gt;
&lt;p&gt;So with that said (and you will never be developing plugins right?), you can use constructor injection with MEF as follows.&lt;/p&gt;
&lt;p&gt;&lt;pre&gt;&lt;code&gt;
[Export(typeof(IPostService))]
public class PostService : IPostService
{
	private IPostRepository _postRepo;
	private IUserRepository _userRepo

	[ImportingConstructor]
	public PostService(IPostRepository postRepo, IUserRepository userRepo)
	{
		_postRepo = postRepo;
		_userRepo = userRepo;
	}

	public Post FetchById(Int32 postId)
	{
		return
			(from p in _postRepo.GetAll()
			 where p.PostId == postId
			 select p as Post).FirstOrDefault();
	}
}

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Don't fret too much though about the all-or-nothing constructor.&amp;nbsp; You have a Factory option later on in this post.&lt;/p&gt;
&lt;h2&gt;Bootstrapping MEF for Application Startup&lt;/h2&gt;
&lt;p&gt;Glenn nailed it right on the head when he called this procedure "bootstrapping."&amp;nbsp; I've always struggled with the proper terminology for this composition process with other Inversion of Control containers.&amp;nbsp; Bootstrapping.&amp;nbsp; Yep, just like my hacked MP3 players have.&lt;/p&gt;
&lt;p&gt;To get things up and running, you will need to to insert some bootstrapping code for your application.&amp;nbsp; This code is required with any type of IoC container, and with MEF as well.&lt;/p&gt;
&lt;p&gt;Below is a small code snippet from a typical ASP.NET MVC 2 global.asax file.&amp;nbsp; Notice I added the two using blocks at the end of the Application_Start().&amp;nbsp; This process would be the same for any type of application you have.&lt;/p&gt;
&lt;p&gt;&lt;pre&gt;&lt;code&gt;
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;

protected void Application_Start()
{
	AreaRegistration.RegisterAllAreas();

	RegisterRoutes(RouteTable.Routes);

	using (var catalog = new DirectoryCatalog(@".\"))
	{
		using (var container = new CompositionContainer(catalog))
		{
			container.ComposeParts(this);
		}
	}
}

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Now, this code is running from with the website assembly.&amp;nbsp; If you, like me, create a seperate assembly to hold your Domain and Repository models, then you simply reference the assembly by replacing the 'this' keyword with Assembly.GetAssembly(typeof(MyProject.Domain)).&amp;nbsp; And yes, you can reference multiple catalogs and assemblies and build up your list as well.&lt;/p&gt;
&lt;p&gt;Note that I included the namespaces here.&amp;nbsp; This is important as normally this bootstrapping code is in the Hosting namespace.&amp;nbsp; What they don't tell you is there is an extension in the namespace one higher for CompositionContainer, that enables the ComposeParts() extension method in the System.ComponentModel.Composition namespace.&lt;/p&gt;
&lt;p&gt;There are tons of options here with the composition containers.&amp;nbsp; Please refer to the .NET 4 documentation on MEF, as well as Glenn's article for a few more tips.&amp;nbsp; You can specify an assembly to reference for the catalog.&amp;nbsp; You can have aggregated catalogs for grouping/namespacing purposes.&amp;nbsp; And yet, you can still have that aged-old configuration file if you really really really want to manually register (export) each type.&lt;/p&gt;
&lt;h2&gt;All Parts are Singletons, out of the box&lt;/h2&gt;
&lt;p&gt;Yep.&amp;nbsp; All of your part's instances are composed and referenced throughout all of your code as singletons (or "statics").&amp;nbsp; This is a great solution for that stubborn developer you may have working in your group that just won't let go of static managers.&amp;nbsp; Make it instance based, and slap an [Export] on it.&amp;nbsp; Done, now use [Import] wherever you like.&lt;/p&gt;
&lt;p&gt;This is important to note because Castle and StructuredMap both default to transient composition (Unity uses whatever you configured the container to use as default).&amp;nbsp; So, make sure you are coding to be thread-safe if you are making the switch over to MEF.&lt;/p&gt;
&lt;p&gt;But do not fret, it's easy to specify the lifestyle within the contract definitions.&amp;nbsp; There are three possible configurations you can set with the [PartCreationPolicy()] attribute:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;CreationPolicy.Shared (singleton, default) 
&lt;li&gt;CreationPolicy.NonShared (transient) 
&lt;li&gt;CreationPolicy.Any&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;The "Any" option is interesting as it leaves it up to the context configuration of the host and/or the configuration of the [Import] contract to specify.&amp;nbsp; You can use RequiredCreationPolicy on the [Import] contract definition to specify the preference.&lt;/p&gt;
&lt;p&gt;&lt;pre&gt;&lt;code&gt;
[PartCreationPolicy(CreationPolicy.Any)]
[Export(typeof(IUserAccountService))]
public class UserAccountService : IUserAccountService
{
	...
}

public class Post
{
	public Int32 PostId { get; set; }
	public String Title { get; set; }
	...

	[Import(RequiredCreationPolicy=CreationPolicy.NonShared]
	public IUserService UserService { get; set; }
}

&lt;/pre&gt;&lt;/code&gt;
&lt;p&gt;There is a problem with this concept though.&amp;nbsp; With a current project we are working on at the moment, we identified the need to have a security context around our services to ensure the current WebRequest has the correct security credentials.&amp;nbsp; With this, we elected to use Castle's WebRequest lifestyle feature.&amp;nbsp; Sadly, this is not possible (yet) with the PartCreationPolicy.&amp;nbsp; So it is left up to the implementer to handle custom composition on their own with a Factory pattern (see below).&lt;/p&gt;
&lt;h2&gt;Lazy Loading within Entities&lt;/h2&gt;
&lt;p&gt;Those of you that are wanting Lazy Loading within your entities, but are struggling with a solution that is compatible with Inversion of Control, fear not!&amp;nbsp; The answer is now possible with MEF.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;
public partial class Post
{
	[Range(0, Int32.MaxValue)]
	public Int32 PostId { get; set; }
	
	[Required, StringLength(64, MinimumLength = 5)]
	public String Title { get; set; }

	[Required, StringLength(1024, MinimumLength = 5)]
	public String Description { get; set; }

	[Required, StringLength(Int32.MaxValue, MinimumLength = 5)]
	public String Body { get; set; }

	[Required]
	public Guid AuthorId { get; set; }

	[Import]
	public IUserService UserService { get; set; }

	private User _user;
	public User Author
	{
		get
		{
			if (_user == null)
				_user = UserService.FetchById(this.AuthorId);
			return _user;
		}
	}
}

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;With our updated Post entity, notice we now have a dependency on IUserService marked with the [Import] attribute.&amp;nbsp; Yep, MEF composes that for you, and you have the UserService to access your lazy objects as needed.&lt;/p&gt;
&lt;h2&gt;Using MEF as a Static Wrapper&lt;/h2&gt;
&lt;p&gt;Time and time again I find myself writing wrapper classes around static members of a 3rd party component, just so I can unit test my code without having to rely on that static class.&amp;nbsp; Using MEF, if you haven't guesses already, is just as easy as you might think.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;
public class Loggerpart
{
	[Export]
	public ILogger Logger
	{
		get
		{
			return LogManager.GetLogger("LoggerInstance", "config");
		}
	}
}

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;This pattern allows you to make a wrapper around any 3rd party or legacy code.&lt;/p&gt;
&lt;h2&gt;MEF Composition with a Factory Pattern&lt;/h2&gt;
&lt;p&gt;Here's another one not in Glenn's article.&amp;nbsp; How to use MEF with a factory pattern to initiate a complex type.&lt;/p&gt;
&lt;p&gt;&lt;pre&gt;&lt;code&gt;
public class UserService : IUserService
{
	public UserService(ISecurityContext securityContext)
	{
		...
	}
}

public class UserServiceFactory
{
	[Export(typeof(IUserService))]
	[PartCreationPolicy(CreationPolicy.Shared)]
	public IUserService Instance
	{
		get
		{
			var context = HttpContext.Current;
			var securityContext = 
				SecurityContextProvider.Setup(context)
			return new UserService(securityContext);
		}
	}
}

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Notice how the UserService is not exported?&amp;nbsp; Instead, we designate a property member of UserServiceFactory called Instance as the Export composition location.&amp;nbsp; &lt;/p&gt;
&lt;p&gt;Remember, you are only Exporting for Composition at runtime.&amp;nbsp; Nothing gets composed during your unit tests, as you are mocking them.&amp;nbsp; So anywhere you use [Import] will be still be mockable for any of your unit tests with this pattern.&lt;/p&gt;
&lt;h2&gt;Exporting with Multiple Contracts&lt;/h2&gt;
&lt;p&gt;Here's a nice trick, you can specify multiple Export contracts for multiple types.&amp;nbsp; Why would you do this?&amp;nbsp; If you are a big DDD follower, you may be using IUserService and IAccountService combined to give you an UserAccountService part.&lt;/p&gt;
&lt;p&gt;&lt;pre&gt;&lt;code&gt;
[Export(typeof(IUserService))]
[Export(typeof(IAccountService))]
public class UserAccountService : IUserService, IAccountService
{
	...
}&lt;/code&gt;&lt;code&gt;
&lt;/pre&gt;&lt;/code&gt;
&lt;p&gt;&lt;/p&gt;
&lt;h2&gt;MEF Does Not Blow Up on Rejection&lt;/h2&gt;
&lt;p&gt;This one is going to take some getting used to.&amp;nbsp; As Glenn mentions, MEF does not throw exceptions if a part cannot be satisfied.&amp;nbsp; It simply will not exist in the object graph for MEF to return - you'll get a null, and will most likely see a NullReferenceException in your containing code that is trying to use the part you wanted to import.&lt;/p&gt;
&lt;p&gt;MEF will simply reject the request for the Import of a part for a number of reasons.&amp;nbsp; For example, if there is no part defined as the correct Export contract type.&amp;nbsp; Say you wanted to import IUserService, but only exported UserService with [Export] and no contract type of IUserService was defined.&amp;nbsp; That was the typical one I found myself forgetting to do.&amp;nbsp; As recommended above, always include the Contract Type when designated a part as Export with [Export(typeof(IUserService))].&lt;/p&gt;
&lt;p&gt;I agree that MEF's Rejection policy is a power feature because it stabilizes the code and allows debugging.&amp;nbsp; Glenn links to a good article on why to ensure application stability: &lt;a title="http://blogs.msdn.com/gblock/archive/2009/08/02/stable-composition-in-mef-preview-6.aspx" href="http://blogs.msdn.com/gblock/archive/2009/08/02/stable-composition-in-mef-preview-6.aspx"&gt;http://blogs.msdn.com/gblock/archive/2009/08/02/stable-composition-in-mef-preview-6.aspx&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;But in short, if you get Rejection happening quite often, check your Export contract definition on your part.&lt;/p&gt;
&lt;h2&gt;In Summary&lt;/h2&gt;
&lt;p&gt;As you can see, it is dead simple to use MEF.&amp;nbsp; The Export functionality is what was missing with Unity, and completely with all other IoC containers.&amp;nbsp; And, it's what gives MEF such great, simplistic power.&amp;nbsp; I highly recommend reading through Glenn's complete article, as he covers a few other concepts such as using the new &lt;strong&gt;Lazy&amp;lt;T&amp;gt;&lt;/strong&gt; for importing lazy exports and metadata.&lt;/p&gt;
&lt;p&gt;Some additional things Glenn covers is the very strong support for debugging and tracing, things you want to be aware of if you use MEF even moderately.&amp;nbsp; He also hints at the up-n-coming support for MEF with IronRuby.&amp;nbsp; He also covers some external links, which I will list here (for my own archiving purposes):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://codebetter.com/blogs/glenn.block/archive/2009/05/14/customizing-container-behavior-part-2-of-n-defaults.aspx" target="_blank"&gt;Customizing Container Behavior Part 2 of N - Defaults&lt;/a&gt; for Facilities 
&lt;li&gt;&lt;a href="http://mef.codeplex.com/releases/view/33536" target="_blank"&gt;MEF Analysis Tool (mefx) for .NET 4.0&lt;/a&gt; for debugging those contracts in large projects 
&lt;li&gt;&lt;a href="http://blogs.msdn.com/dsplaisted/archive/2009/06/08/a-crash-course-on-the-mef-primitives.aspx" target="_blank"&gt;A Crash Course on the MEF Primitives&lt;/a&gt; for the underlying "quantum universe of MEF, its über extensibility points" as Glenn says&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;Once concept I am tinkering with is utilizing the [Import] attribute in the attributed programming model of MEF to define the complete contexts of my BDD tests for me with all dependencies already mocked up and ready, with T4 templates largely driving that effort.&lt;/p&gt;
&lt;p&gt;MEF wacked me upside the head.&amp;nbsp; It does everything right, and even allowed me to step back and realized, "Dang. I was bloating my code."&amp;nbsp; Yes, they have done it right.&amp;nbsp; So right that the next project I am starting this week will be on Visual Studio 2010 RC - not even released yet.&amp;nbsp; &lt;/p&gt;&lt;img src="http://eduncan911.com/aggbug.aspx?PostID=6964" width="1" height="1"&gt;</description><category domain="http://eduncan911.com/archive/tags/Geek+Stuff/default.aspx">Geek Stuff</category><category domain="http://eduncan911.com/archive/tags/Computer+Programming/default.aspx">Computer Programming</category><category domain="http://eduncan911.com/archive/tags/Asp.Net+Mvc/default.aspx">Asp.Net Mvc</category><category domain="http://eduncan911.com/archive/tags/MSpec/default.aspx">MSpec</category><category domain="http://eduncan911.com/archive/tags/Inversion+of+Control/default.aspx">Inversion of Control</category><category domain="http://eduncan911.com/archive/tags/MEF/default.aspx">MEF</category></item><item><title>Registering MSpec runners for TestDriven.NET on Windows x64</title><link>http://eduncan911.com/blog/registering-mspec-runners-for-testdriven-net-on-windows-x64.aspx</link><pubDate>Wed, 20 Jan 2010 17:59:00 GMT</pubDate><guid isPermaLink="false">3cbf8099-f611-4197-a0f5-c5a9f8954971:6951</guid><dc:creator>Eric A. Duncan</dc:creator><slash:comments>2</slash:comments><comments>http://eduncan911.com/comments/6951.aspx</comments><wfw:commentRss>http://eduncan911.com/commentrss.aspx?PostID=6951</wfw:commentRss><description>&lt;P&gt;EDIT:&amp;nbsp;MSpec v0.3 now supports &lt;A href="http://weblogs.asp.net/nunitaddin/archive/2009/11/05/testdriven-net-2-24-xcopy-deployable-test-runners.aspx"&gt;TestDriven.Net's v2.24 XCopy Deployable Test Runners&lt;/A&gt;.&amp;nbsp; So this blog post is legacy information at this time.&amp;nbsp; &lt;/P&gt;
&lt;P&gt;&lt;IMG style="BORDER-BOTTOM:0px;BORDER-LEFT:0px;DISPLAY:inline;MARGIN-LEFT:0px;BORDER-TOP:0px;MARGIN-RIGHT:0px;BORDER-RIGHT:0px;" title=td_rocket2[1] border=0 alt=td_rocket2[1] align=left src="http://eduncan911.com/blog/thumbnail/MSpecrunnersforTestDrive.NETonWindowsx64_AD3B/td_rocket21.gif" width=141 height=100&gt; Machine.Specifications (MSpec) is my preferred Behavior-Driven Design (BDD) framework for Microsoft.NET.&amp;nbsp; Aaron Jensen, &lt;A href="http://codebetter.com/blogs/aaron.jensen/archive/tags/mspec/default.aspx" target=_blank&gt;the author of MSpec&lt;/A&gt;, released support for TestDriven.NET, xUnit, nUnit, and Gallio.&amp;nbsp; And with the latest release of v0.3, it adds official support for ReSharper's Unit Tests and and Selenium integration testing.&amp;nbsp; Very cool stuff indeed, and a very active project!&lt;/P&gt;
&lt;P&gt;What has bugged me a bit is getting TestDriven.NET to see my MSpec specifications, on my Windows 7 x64 platform.&amp;nbsp; Aaron so kindly includes a InstallTDNetRunner.bat file to register MSpec with TestDrive.NET; but, it only works on x86 systems.&lt;/P&gt;
&lt;P&gt;So why does it not work with x64 systems?&amp;nbsp; It is because the installer for TestDriven.NET registers the runners in a different registry location.&lt;/P&gt;
&lt;H2&gt;Windows Vista/7 x64 (64-bit) MSpec runner TestDriven.NET registry file&lt;/H2&gt;
&lt;P&gt;Below, I have created a bat file you can copy and paste into your own InstallTDNetRunner-x64.bat if you are on Windows x64.&amp;nbsp; Or, you can download it from here: &lt;/P&gt;
&lt;P&gt;&lt;A href="http://eduncan911.com/blog/binary/legacy/InstallTDNetRunner-x64.zip"&gt;http://eduncan911.com/blog/binary/legacy/InstallTDNetRunner-x64.zip&lt;/A&gt; &lt;/P&gt;&lt;PRE&gt;&lt;CODE&gt;

@echo off &amp;amp; if not "%ECHO%"=="" echo %ECHO%

setlocal
set LOCALDIR=%~dp0

echo Windows Registry Editor Version 5.00 &amp;gt; MSpecTDNet.reg
echo [HKEY_CURRENT_USER\Software\MutantDesign\TestDriven.NET\TestRunners\MSpec] &amp;gt;&amp;gt; MSpecTDNet.reg
echo "Application"="" &amp;gt;&amp;gt; MSpecTDNet.reg
echo "AssemblyPath"="%LOCALDIR:\=\\%Machine.Specifications.TDNetRunner.dll" &amp;gt;&amp;gt; MSpecTDNet.reg
echo "TargetFrameworkAssemblyName"="Machine.Specifications" &amp;gt;&amp;gt; MSpecTDNet.reg
echo "TypeName"="Machine.Specifications.TDNetRunner.SpecificationRunner" &amp;gt;&amp;gt; MSpecTDNet.reg
echo @="5" &amp;gt;&amp;gt; MSpecTDNet.reg
echo. &amp;gt;&amp;gt; MSpecTDNet.reg

echo [HKEY_LOCAL_MACHINE\SOFTWARE\MutantDesign\TestDriven.NET\TestRunners\MSpec] &amp;gt;&amp;gt; MSpecTDNet.reg
echo "Application"="" &amp;gt;&amp;gt; MSpecTDNet.reg
echo "AssemblyPath"="%LOCALDIR:\=\\%Machine.Specifications.TDNetRunner.dll" &amp;gt;&amp;gt; MSpecTDNet.reg
echo "TargetFrameworkAssemblyName"="Machine.Specifications" &amp;gt;&amp;gt; MSpecTDNet.reg
echo "TypeName"="Machine.Specifications.TDNetRunner.SpecificationRunner" &amp;gt;&amp;gt; MSpecTDNet.reg
echo @="5" &amp;gt;&amp;gt; MSpecTDNet.reg
echo. &amp;gt;&amp;gt; MSpecTDNet.reg

echo [HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\MutantDesign\TestDriven.NET\TestRunners\MSpec] &amp;gt;&amp;gt; MSpecTDNet.reg
echo "Application"="" &amp;gt;&amp;gt; MSpecTDNet.reg
echo "AssemblyPath"="%LOCALDIR:\=\\%Machine.Specifications.TDNetRunner.dll" &amp;gt;&amp;gt; MSpecTDNet.reg
echo "TargetFrameworkAssemblyName"="Machine.Specifications" &amp;gt;&amp;gt; MSpecTDNet.reg
echo "TypeName"="Machine.Specifications.TDNetRunner.SpecificationRunner" &amp;gt;&amp;gt; MSpecTDNet.reg
echo @="5" &amp;gt;&amp;gt; MSpecTDNet.reg

regedit MSpecTDNet.reg

del MSpecTDNet.reg


&lt;/CODE&gt;&lt;/PRE&gt;
&lt;H2&gt;Setup TestDriven.NET and MSpec&lt;/H2&gt;
&lt;P&gt;Still a bit confused, getting TestDriven.NET and MSpec setup for the first time? Here's the steps to follow:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Go ahead and install TestDriven.NET.&amp;nbsp; It can be installed and upgraded at any time. &lt;/LI&gt;
&lt;LI&gt;Next, grab &lt;A href="http://codebetter.com/blogs/aaron.jensen/archive/tags/mspec/default.aspx" target=_blank&gt;the latest release of MSpec&lt;/A&gt;&amp;nbsp; and extract the zip to a semi-permanent location.&amp;nbsp; This is because things such as ReSharper and TestDriven.NET will need to know a common location for the mspec assemblies.&amp;nbsp; I recommend C:\Program Files (x86)\MSpec\. 
&lt;UL&gt;
&lt;LI&gt;Included with the MSpec zip is an InstallTDNetRunner.bat, but it only works on 32-bit Windows.&amp;nbsp; For 64-bit Windows, you want to copy my registry code above into a new file called InstallTDNetRunner-x64.bat. &lt;/LI&gt;
&lt;LI&gt;Make sure to place this InstallTDNetRunner-x64.bat file in the same directory as your semi-permanent MSpec location above. &lt;/LI&gt;&lt;/UL&gt;&lt;/LI&gt;
&lt;LI&gt;Finally, you want to double-click and execute the InstallTDNetRunner or InstallTDNetRunner-x64 from within this semi-permanent location.&amp;nbsp; This will insert the registry values for a new runner called MSpec for TestDriven.NET to detect and execute. &lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;From this point further, you can right-click within different places to execute your specifications within your MSpec.&amp;nbsp; Some tips on locations you can right-click and execute the specs:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;The project file: will execute all specs detected within that project. &lt;/LI&gt;
&lt;LI&gt;The Namespace: will execute all specs detected within that namespace throughout the project. &lt;/LI&gt;
&lt;LI&gt;Within the &lt;FONT face="Courier New"&gt;Establish context&lt;/FONT&gt; or &lt;FONT face="Courier New"&gt;Because of&lt;/FONT&gt; : Will execute all specs within that one class/scenario. &lt;/LI&gt;
&lt;LI&gt;Within the &lt;FONT face="Courier New"&gt;It&lt;/FONT&gt; spec - Will execute just that one test. &lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;Something to note is Aaron is currently upgrading MSpec (version 0.4, not released yet) to support TestDriven.NET's new 2.24 feature of version independent runners. I haven't looked completely into that myself, but should make registring TDNet runners in the future a bit easier.&lt;/P&gt;&lt;img src="http://eduncan911.com/aggbug.aspx?PostID=6951" width="1" height="1"&gt;</description><category domain="http://eduncan911.com/archive/tags/Computer+Programming/default.aspx">Computer Programming</category><category domain="http://eduncan911.com/archive/tags/MSpec/default.aspx">MSpec</category></item></channel></rss>