Managed Application Framework – Part 1 – The Beginnings!

Last week I was tasked with developing a new App for the guys I work with, (not a developers app you understand, but for actual normal users!!! Luckily it puts me smack bang where I work best – developing functional, extendable (and most importantly) Windows based apps. I’m now officially in my comfort zone!

The main difference between this app and previous apps I’ve done is the customer, normally I’m the person who writes that software tool that the other devs or system admins will use, so I can cram in shed loads of functionality and what I think are cool UI’s – usually involving liberal use of the SandDock tools (http://www.divelements.com/). This time because the users are non-expert users I’m having to really consider the design of the UI, and it is (in this case) very important – one of the specs of the app is: ‘It has to look cool’.

There is actually a reason for it to look cool – because we need it to impress management to get the go-ahead to redo an older app. Up side of this is that it’s going WPF. Aces!

Woah, I appear to have got a little bit sidelined.. I actually started this post to talk about the Managed Add-In Framework (MAF) of .Net 3.5. The MAF is a framework for using Add-In’s (or plugins as some apps call them) within .NET, but without the hassle of writing your own code to do the cool stuff (reflecting to load dlls etc).

As it happens MAF fits very nicely into the app I’m designing at the moment, so I’ve been playing around with it for a week or so now, and I have to say, I’m very impressed, the design of the MAF has been extremely well thought out, and covers a hell of a lot!

What does MAF consist of? Basically 3 broad parts, Host – Pipeline – Addin, of which the pipeline can be broken down into: HostView – HostAdapter – Contract – AddInAdapter – AddInView. The reason this is important is that the pipeline seperates the Host and AddIn from being dependent on the Contract (which in a later post will prove to be incredibly useful).

In this post (below) I’m going to explain how to set up a simple quick MAF application, just to get the swing of things, so.. without further ado: the MAF.

Firstly it’s important to know that the MAF requires a certain folder structure to work, (I think it requires it, every example, sample etc I’ve seen has it!). The structure can be seen on MSDN at: http://msdn2.microsoft.com/en-gb/library/bb384240.aspx – This is why I’ve put the fact that you need to set the output folders in the properties for projects created to point to a non-default location.

We begin creating a MAF project with a Class Library project we’re gonna call ‘Contracts’. In it we define the contract we intend to make all our Add-Ins implement.

  1. New Class Library – ‘Contracts’, set the Build Output to be: ..\Output\Contracts
  2. Add references to: System.AddIn and System.AddIn.Contract
  3. Define new interface, which must implement the IContract interface, and have the AddInContract attribute.


[AddInContract]
public interface IHelloMAFContract : IContract
{
string HelloMAF();
}

  1. Build the one project, all ok? Good, let’s mosey on!
  2. Get and install the Pipeline builder (open source) from codeplex: http://www.codeplex.com/clraddins
    (All the instructions are on the interweb at that site).
  3. Run the Pipeline builder and create the pipeline, this creates the 4 extra projects (HostView, AddInView, AddInSideAdapters and HostSideAdapters projects). This saves us the time of writing this code ourselves (which involves quite a lot of code repetition).
  4. Build the solution, you should have 5 projects now. Assuming that went ok, lets carry on.
  5. Create an Add-In —
    a) Add a new Class Library project to the solution, call it something like ‘AddInV1’
    b) Set the build output location to be: ..\Output\AddIns\V1
    c) Reference in the AddInView DLL which will be in the Output\AddInView directory.
    Set this reference’s ‘Copy to local’ property to ‘FALSE’.
    d) Reference in System.AddIn
    e) Edit the class file and create the code to implement the IHelloMAF contract:


[AddIn("AddInV1", Version="1.0.0.0")]
public class AddInV1 : IHelloMAF
{
public string HelloMAF() { return "Hello MAF!!"; }
}

In this code we’ve attached the ‘AddIn’ attribute, which takes a name (which can’t have spaces) and then a set of named properties (intellisense is your friend here). Also of note is that in our ‘Contracts’ project we called the contract: IHelloMAFContract, whereas here we’re using IHelloMAF. The code does nothing impressive, just returning a string.

  1. Build the solution, if you look in your output folder you should now have a \Addins\V1 directory with the dll in it. That’s the Add-In created.

  2. Now we’re going to create a host to actually run the Addins
    a) Create a new Console Application (call it something memorable, ‘host’ for example :))
    b) Reference the HostView dll (copy to local = false) and the System.AddIn dll.
    c) Set the build output location to: ..\Output
    d) In the Program.cs file, put in the following:


public static void Main()
{
string path = Environment.CurrentDirectory;
//Update the AddInStore looking for the AddIns.
AddInStore.Update(path);

//Get the tokens from the AddInStore.
Collection tokens = AddInStore.FindAddIns(typeof(IHelloMAF), path);

Console.WriteLine("Found " + tokens.Count + " addins, activating them....");

foreach(AddInToken token in tokens)
{
//Activate a given token.
IHelloMAF addin = token.Activate( AddInSecurityLevel.Internet );
Console.Write( "\tAddin: " + token.Name + ", version: " + token.Version + " --> " );
Console.WriteLine( addin.HelloMAF() );
}

Console.WriteLine();
Console.WriteLine( "Fin. Press ENTER to exit." );
Console.ReadLine();
}

What we have here are 3 main points, firstly where we do: AddInStore.Update(path); We’re telling the AddInStore to update itself and look for AddIns with the given root path.

Next point is the AddInStore.FindAddIns(typeof(IHelloMAF), path); line, which basically asks the AddInStore to find the AddIns available of a given type.

The final point is the activation of the AddInToken – token.Activate( AddInSecurityLevel.Internet );. At this point we’re activating the Add-In, and in the next lines calling methods on it.

  1. Build the solution.
  2. Start debugging (F5).

Running this should now give us:

> Found 1 addins, activating them....
> Addin: AddInV1, version: 1.0.0.0 --> Hello MAF!!
> Fin. Press ENTER to exit.

That’s the basic Host Pipeline AddIn structure, and will provide you with a good basis, the next step is to consider what to do in the event that we want to change the contract…

Jamendo

Not a development post (in the true meaning of the word :)) but more about a website I found a few days ago… Jamendo.com – I spend my coding time listening to music, it’s how I work and particularly with the distractions of an office with other people, it’s often the only way to ‘zone in’ to the work.

Jamendo provides a collection of royalty free music, free to download and share etc. It’s given me more options to listen to now, so that’s a good thing.

Check it out and see what you think!

Ternary operators don’t work with nullable value types?

I’ve got the following situation:

DateTime? myDt = (DateTime) row["Column"];

This fails when retrieving a DBNull value, so we check for that:

DateTime? myDT = (row["Column"] == DBNull.Value) ? null : (DateTime) row["Column"];

This won’t compile, however doing:


DateTime? myDT;
if(row["Column"] == DBNull.Value)
myDT = null;
else
myDT = row["Column"];

works fine, now, I realise I can simplify that statement, but, for the purposes of this post, it is a closer match to the ternary operator.

Why won’t the ternary op work with the value type? It works perfectly with a string…

Missing format specifier.

I’ve been practicing my F# recently – I took a gap for a little bit, and just got back into it. I’ve been working through my ‘Foundations of F#’ book, and have hit a slight snag.

There is one line of code I can’t get to compile, I get the ‘Missing format specifier.’ error for the following line:

let print x = printfn “A%” x

The intellisense highlights under the “A%” bit.. Any ideas?

The hunt continues!
Update – worked it out, it should be “%A” rather than “A%” – looks like a typo!!

Printing a word document from C# – how the **** do you change the paper type???????

You wouldn’t have thought it would be that hard to print word documents from within C# – hook up the project to the Word Interop dlls – open the document and print. Easy.

In fairness – a lot of it is like this – and setting up a printer is pretty easy;

PrintDocument pd = new PrintDocument();
pd.PrinterSettings.PrinterName = printerName;
word.ActivePrinter = printerName;
word.PrintOut(....)

Even selecting a given tray is manageable – either via the ‘WdPaperTray’ enum – or even searching for it via a string.
But try as I might – I cannot find a way to change the paper type – and by that I mean from ‘Plain’ to ‘Preprinted’.

The basic problem is that I need to print to (say) ‘Tray 1’ which contains ‘Preprinted’ paper – and is set up as so on the printer. Attempting to print a plain paper printout gets stuck at the printer with a Paper type is mismatched error – which is fair enough.

Does anyone know how to do this????

Setting up TeamCity…

I’m gradually in the process of shifting our CruiseControl based CI service to use JetBrain’s TeamCity Professional solution (both are free).

The main reason for moving to TeamCity is that whilst CruiseControl worked and did our CI adequately, TeamCity provided more bang for your buck (and when the buck is 0, it’s win-win). TC is effectively CC but with a nicer front end and provision for stats about the builds etc. It’s definitely worth checking out if you are just getting into CI. The only major drawback is the source control integration it has – i.e. it only works with selected source control solutions at the moment (SourceSafe etc) – If you have one of these SCC then give it a try!

Anyhews – migration – easy?
Yes and no – Adding my VS2008 projects to TeamCity was a breeze – they’d never been CC’d so no migration required – just point TC to the SourceSafe database, and then tell it which sln file to open.

Migrating the existing VS2005 projects has been a bit harder, and to be honest most of it is to do with the unit test setup, and they way we have some of our solutions setup – dependency nightmares. I’m pretty certain this is covered by a thing called ‘Artifacts’ in the TC world, but I have yet to explore them properly.

Setting up a TC project consists of 3 main steps,
1. Name the project, describe it etc, decide on the numbering of builds – so you can have 1.x where ‘x’ increments, or just ‘x’ (which is default & the same as cruise control).
2. Set up the source control – point it to the right root project, give it a check out name (or not should you choose).
3. Set up the build runner – in all my cases – based on an sln file, but you can use MSBuild, Ant and many more. This is the usual stuff – configuration, etc.

This is enough to get it to run, but there are even more options – you can set up dependencies, triggers and ‘Agent requirements’.

Agents are one of the really cool things about TC, an Agent is basically a machine that does the compilation. You can have 3 Agents in the Professional edition (and pay for more if needed). At the moment the build server we have doesn’t have .NET 3.5 installed on it, so my VS2008 applications won’t build there, but (obviously) my machine does. So I can have one Build Agent on the build server – for all .NET 2.0 apps, and then my machine with .NET 3.5 as another agent.

Effectively my machine can build any of the .NET 2.0 solutions as well, so now we can do two builds at the same time. TC knows which agents are idle and pushes the build requests to an idle agent – based on a ‘power’ order, i.e. the most powerful agent first.

Anyhews – a few more projects to migrate!

Invoking UI Changes in WPF

Again another reminder, in WinForms I would have done:

private delegate void UpdateUiTextDelegate(Control control, string text);
private void UpdateUiText(Control control, string text)
{
if(InvokeRequired)
{
Invoke(new UpdateUiTextDelegate(UpdateUiText), new object[] {control, text});
return;
}
control.Text = text;
}

Using the same delegate we need to use the Dispatcher.Invoke method – this is (as far as I’m aware at the moment) the sort-of equivalent of the Invoke method on a Form.


private void UpdateUiText(Control control, string text)
{
if(!Dispatcher.CheckAccess())
{
Dispatcher.Invoke(DispatcherPriority.Send, new UpdateUiTextDelegate(UpdateUiText), control, text);
return;
}
control.Text = text;
}

To be honest, I think I’ve read somewhere that the Dispatcher isn’t equivalent – but it does the job for now… I need to read into it more!

Enabling / Disabling buttons in WPF

I’m really only putting this in to remind myself — having come from a WinForms background, I’m used to:

_btnOK.Enabled = false;

but in WPF this is:

_btnOK.IsEnabled = false;

For some reason I (without fail) forget this!

WPF – working with designers – will it work?

One of the main advantages of WPF is that you can write all the backend code and then shunt the design work to a professional designer – you know – one of those guys who thinks that Cyan and Magenta just don’t go together.

I’ve been knocking up a couple of WPF apps in the past month or so and have some very basic Windows pieced together. The app basically works, and now I’m looking at passing the XAML to the designer to get her to make it look good. It’s kind of exciting – I’m really interested to see what she’ll come up with – given free reign and a package hopefully allowing her to do what she wants.

She’ll be predominantly using Expression Blend (and presumably Photoshop) to do the design work. I guess my only reservation is that designing an application where you can use timelines etc is a different kettle of fish to a website, and I hope that we can work together to put some of the cooler WPF stuff into the app.

The other concern is how it will work – should I just give her a document detailing the data that needs to be represented and let her make the window up as she likes, or should I knock up a basic window and then she can just rip it apart etc (again as she likes)…??

I’ll try to blog more when I know how the process is going to go and keep up to date on how it is actually going.

Here’s going forward optimistically!

Consolas!!! GRRRRRR

Why oh why does everyone and their Dad now use Consolas???
Am I the only one that perceives the font as ‘fuzzy’? I’ve read quite a few blogs recently loving the Consolas font such as Coding Horror, and as far as I’m aware – it was made to be a programmers font. But in the examples I’ve seen they’re always font size 11+. Now – I code in a font size of 8 – and to me – this makes Consolas fuzzy (see pictures below)

LINQPad in Consolas:
Consolas Font

LINQPad in OCR A Extended:
OCR A Extended

Is it just me who sees this???