Assembly-level initialization at design time

April 7, 2010

One sorely missing feature from the Blend 4 Beta is the ability to have a method in which you can perform initialization work specific to design-time.  Such a method is useful for tasks like loading design-time data services into a container, configuring MEF with design-time specific dependencies, and basically anything else that you might otherwise do at startup when the application runs.  Since your App class won’t be started up when in design mode, it would be great if there was a way for Blend to call a method designated for that purpose at design-time.

I have been thinking about this a lot recently.  Initially I thought that Blend could provide an attribute that I could apply to a static method, and it would then invoke that decorated method before loading any Views.  That seemed like the best solution (and still does, in my opinion).  However, since Blend has no such attribute, I figured it was a moot point…until I realized that I could create my own attribute for the same purpose!

If you decorate an assembly with an attribute, that attribute must be instantiated when the assembly is inspected via reflection (which Blend most certainly does).  So, I simply created a custom attribute and applied it to my assembly.  In that attribute’s constructor, I check to see if it was loaded into design-time.  If it was, I then perform my initialization logic.  How simple!

Here’s the code I added to AssemblyInfo.cs in a project loaded by Blend 4 Beta:

I assume people might want to genericize this class a bit, but the basic idea is quite simple.  Perhaps adding a Type parameter for a class to instantiate would be better, so that the instantiated class could handle initialization.  That would leave the attribute very simple and reusable.  I’ll leave that up to you, if you care…

Here’s the code, for copy-and-paste purposes:

// In AssemblyInfo.cs
//
// Apply this attribute to the assembly so
// that it will be created when the assembly
// is loaded into memory.
[assembly: DesignTimeBootstrapper]

[AttributeUsage(AttributeTargets.Assembly)]
class DesignTimeBootstrapperAttribute
: Attribute
{
public DesignTimeBootstrapperAttribute()
{
var dep = new DependencyObject();
if (DesignerProperties.GetIsInDesignMode(dep))
{
// TODO: Design-time initialization…
}
}
}

Happy coding!


The ultimate hack for Silverlight in Blend

January 6, 2010

I recently needed to write some design-time support for a Silverlight framework.  I needed to discover a solution’s assemblies while running in Blend, and then pass those assemblies downstream for further processing.  In WPF, using the full .NET framework, that’s easy: just call AppDomain.CurrrentDomain.GetAssemblies() and then filter them based on the Location property.  In Silverlight, however, a couple of problems showed up that seemed to make this task impossible.

First, the Assembly.Location property is marked ‘Security Critical’ in Silverlight 3.  This means that if you access the property, an exception will be thrown.

Second, Silverlight 3’s AppDomain class does not have a GetAssemblies method!

It turns out that both of these problems are easy to overcome.  The key thing to know is that when Silverlight code is running in Blend, it’s actually executing against the regular .NET Framework (the same one that WPF uses).  You can access ‘Security Critical’ members and no errors occur.  That takes care of the Assembly.Location issue.  Even though the Silverlight code you write, that is intended to run in Blend, can only access the Silverlight API, you can still access the full .NET framework’s API via reflection.  This allows you to work around the second issue.  For example:

var assemblies = typeof(AppDomain)
   .GetMethod("GetAssemblies")
   .Invoke(AppDomain.CurrentDomain, null);

Remember, this hack only works when your Silverlight code is running in Blend! This will not work when running under normal circumstances, since Silverlight apps normally only have access to the Silverlight subset of the .NET Framework.

Happy coding!


Brennon Williams Sweetens the Pot

May 21, 2008

The Podder Skinning Competition is at full speed now! The first place winner now stands to also win a copy of the new book Microsoft Expression Blend Unleashed, courtesy of Brennon Williams. Brennon is the author of that book, and also the newest WPF Disciple. Thanks a lot, Brennon!


The importance of learning Expression Blend

February 18, 2008

A few days ago I was visiting the Infragistics headquarters.  I set aside half an hour to stop by Grant Hinkson‘s office.  Grant is the Visual Designer working on a new skin for Podder.  I wanted to check in with him, and work through any issues or questions that might have cropped up during his work on his new Podder skin.  I had a WPF revelation within those thirty minutes.

For this project, Grant is acting solely in the capacity of Visual Designer.  He is a good Developer, but I don’t want him to need those skills for this project.  My objective is to design Podder in such a way that he, the Visual Designer, never has to write a line of code.  Naturally, this means that he is living in Expression Blend to get his work done.  As we worked through little issues and gotchas, I was amazed at how fluent Grant is in Blend.  I must admit, I never use Blend.  He was flying through the menus, dropdowns, panels, etc. so quickly that I could not follow along!

What amazed me even more was the thought processes he went through to get his work done.  As he expertly navigated through Blend, he was saying things like “We’ll need to Storyboard that…I’ll just record a Timeline for this…Now I’ll just trigger the transition off that event…We’ll group those elements together…”  I never, ever say or think things like that when working with WPF.

This experience made me realize that Visual Designers think about WPF in a very different way than Developers.  So different, in fact, that there is a very real potential for a communication barrier to arise between the development staff and the visual design team.  Luckily for me, Grant is an accomplished WPF developer, so we were both pretty much on the same page.  However, it is easy to imagine working with a Visual Designer who does not have the development experience, and having trouble finding a common ground of shared concepts to discuss.  The further away from “visual design” you go, the more murky the communication can become.  For example, how do you discuss the proper way to create a declarative data binding with someone devoid of development experience?

I now believe it is imperative that WPF developers are at least comfortable using Blend.  Even if you have no intention of using Blend on a regular basis, it will prove beneficial as you interact with people who live in Blend.  The thought processes of getting work done, the terminology/lingo, and the artificial limitations imposed by Blend are all things that we, the developers, should know about.  Not only that, but it is a very interesting and powerful tool!

I’m excited to learn Blend!