# Saturday, June 26, 2010

This morning I thought I would sit down with my Mac and play with doing .NET development for OS X. I had previously tried, but always found things to be really frustrating. All the Cocoa bindings were out of date, and the WinForms stuff looked terrible, etc. But Miguel wrote a blog post a while back indicating they are getting serious about developing a native solution for OS X.

I downloaded the experimental version of MonoDevelop 2.4 from Michael Hutchinson blog but quickly found out the experimental version of MonoDevelop (based on 2.4 RC 4) was out dated. So I upgraded to MonoDevelop 2.4, opened it, and noticed that MonoMac wasn't an available add-in in the RTM version of MonoDevelop.

So I did what any self respecting geek would do, I started digging around inside the bundle for the experimental version of MonoDevelop from Michael Hutchinson, and found the MonoMac addin hidden inside at the path MonoDevelop.app/Contents/MacOS/lib/monodevelop/Addins/MonoDevelop.MonoMac. I copied the folder to the appropriate place of the RTM version of MonoDevelop 2.4 and everything works as expected!

Download it

Download MonoDevelop, copy it to your Applications folder. then open the contents of MonoDevelop.app, and extract MonoDevelop.MonoMac to Contents/MacOS/lib/monodevelop/Addins/. Restart MonoDevelop, and now you should be able to create a new MonoMac project!

Update

I missed two other files that updated in MonoDevelop.IPhone, download the new MonoDevelop.Addins.zip (490.49 KB) and extract it to the same place.

Saturday, June 26, 2010 3:02:05 PM (Alaskan Daylight Time, UTC-08:00)
# Friday, April 03, 2009

Background

For a project I'm doing, I have a task model for the various pieces. In the beginning, I was manually creating a List<ITask>. As I kept adding tasks to run, I started thinking about hacking some code together to rifle through my assembly and pull back all the classes which implement ITask.

Then I remember hearing about Managed Extensibility Framework (MEF). I did some searching, found the MEF home page, and even read the MEF overview. But none of that told me what I really wanted to know, what's the fastest way to get started using MEF as a component loader?

I did some more searching and found the dnrTV episode "Glenn Block on MEF, the Managed Extensibility Framework" and after 20-30 minutes they finally got down to how to create a plugin for your app.

But what I really wanted, and I bet a lot of others, is a quick start guide for creating a plugin.

Solution

Download the latest version of MEF, as of this writing its Preview 4. Grab the System.ComponentModel.Composition.dll from the bin folder and stash it somewhere. Make a reference to said dll in your project.

On your plugin class, add Export attribute:

[Export(typeof(IPlugin))]
public class Foo : IPlugin { ... }

In your plugin consumer, create a property to hold your plugins, and add the Import attribute:

[Import(typeof(IPlugin))]
internal IList<IPlugin> _myPlugins { get; set; }

Now, tell MEF where to get the plugins at (line 2), and where you want MEF to fulfill any plugins (line 5):

private void LoadPlugins() { var catalog = new AssemblyCatalog(Assembly.GetExecutingAssembly()); var container = new CompositionContainer(catalog); var batch = new CompositionBatch(); batch.AddPart(this); container.Compose(batch); }

 

I put my call to the LoadPlugins method in the constructor.

Now, spin through your plugins and do the work:

Console.WriteLine("Found {0} plugins", _myPlugins.Count);
foreach (var plugin in _myPlugins) {
    Console.WriteLine(plugin.Name);
}

 

Download the complete source to this (really, only about 10 extra lines to glue things together) and have fun!

kick it on DotNetKicks.com
.NET | C# | HowTo | MEF
Friday, April 03, 2009 8:37:33 PM (Alaskan Standard Time, UTC-09:00)
# Sunday, March 15, 2009

A long time, and many many moons ago I took wrote some code to interface our build server with a network power switch we had laying around the office. We used this to turn on and off lava lamps to indicate the status of the build. Some might ask why we didn't use the X10 support that is already in CCNET, and the answer mostly is cost, and the fact that X10 wouldn't work in our environment.

That was 2.5 years ago. Since then, our team has become more distributed. We have one guy working in Ann Arbor, MI, and occasionally have others telecommuting. So not everyone can see the status of the lamps. Also in the 2.5 years since that code was written, a little thing called Twitter has become very popular. I did some research, and found Tom Fannings nAnt Twitter task and briefly considered using it.

But in the end, I just couldn't resist adding my own developer gold plating and thought it would be neat if we could also issue commands to the build server via tweets. So with that feature in mind, I had to write it myself.

To start out with, I used Yedda's C# Twitter library. The Yedda library is a pleasure to work with, it makes sending a tweet as simple as

new Twitter().UpdateAsXML(_username, password, messsage);

One thing the Yedda library didn't have, was the ability to query for your Twitter replies. A quick look through the source, and the Twitter API docs and I realized this would be trivial. The details of how I did it aren't important to this post, but if your curious, you can look at lines 567 - 627 of the Yedda source included with this post.

I'm not going to dive to much into how the whole project works, but here is a high level. The software runs as a Windows Service, leverages the CCTrayLib assembly for Cruise Control.NET to do all the heavy lifting. It polls the Cruise Control.NET server every 5 seconds, and fires events when things happen. The two events we want are the Polled and BuildOccurred events.

These events allow us to intern kick off our own events based on the state of the build. Based on the state, we grab the appropriate actions to run as defined in the BuildActions.xml file. This maps a build state to a set of actions. In the case of a "Building" action, we send a Twitter, with a message template of "{PROJECT} is building", and turn ports 1 on, and 2 off on our ePower switch. Easy enough.

But how do we take in commands? I pondered this for a minute than realized it would be trivial to leverage the Twitter replies API for this. But what about security, we can't have just anyone sending commands to our build server. This is where the Twitter friends API comes in handy. In order to issue commands to our build server, the account our build server uses has to have you as a friend, not just a follower.

The first action I implemented was the force build command. The idea for the grammar came from a joke reply @orand sent our Twitter bot. After that, I thought it might be nice to be able to get the list of projects, get a projects status, and ask for help. So that leaves us with a total of 4 commands.

A small bunny trail

When I first wrote the command parser, it looked something like this:

if (msg.StartsWith("force build "))
    ProcessForceBuildCommand(msg, user);
else if (msg.StartsWith("get projects"))
    ProcessProjectListsCommand(msg, user);
...

I thought about it for a while, and thought there had to be an easier way. We are using .NET 3.5 after all, with all its lamba, LINQ and new and improved delegate goodness. I did some research and came upon the Action<T> (and Func<T>) delegate type. And came up with this implementation for registering commands

var commands = new Dictionary<string, Action<string, string>>
    {
        {"force build ", ProcessForceBuildCommand},
        {"get projects", ProcessProjectListsCommand},
        {"get project status ", ProcessProjectStatusCommand},
        {"help", ProcessHelpCommand}
    };

Once we have all the commands registered, we can use some lambda and LINQ magic to act upon the commands issued

var key = _commands.Keys.Where(msg.StartsWith).First();
if (!string.IsNullOrEmpty(key))
    _commands[key].Invoke(msg, user);
else
    SendTweet(string.Format("@{0} I'm sorry, I don't understand you. Maybe you should ask for help", user));

Get to the point, I want to see the source code

The code overall is fairly well structured (if I do say so myself), although there is one area where I did violate the separation of concerns rule, the TwitterManager class knows more about Cruise Control.NET than it should. But, given that this is a very simple internal project, and not for public consumption, I'm mostly OK with that :)

I've included the source to our entire build monitor, I hope you find it useful.  We are using a very old version (1.1) of Cruise Control.NET in our environment. If your using a more recent version, you will probably need to swap out the Cruise Control CCTrayLib and Remote assemblies for something more recent, and invert some of the commented out code in the SetupCruiseControl method of BuildServerMonitor.cs

If you have any questions, or find/fix any bugs, please feel free to leave a comment, or send me a tweet, my username on Twitter is akcoder.

Download the Afhcan.BuildMonitor

.NET | C# | HowTo
Sunday, March 15, 2009 7:59:22 PM (Alaskan Standard Time, UTC-09:00)