Tuesday, February 2, 2010

Crossplatform issues with MEF Preview 8

While far from perfect, Magecrawl has a decent amount of modularity. The GameEngine with all map generation and the details of the running world have a hard boundary between it and the GUI. However, I feel that the GameEngine has gotten a bit too big and I'd like to split out of parts of it into separate components.

One of my first tasks this release was to investigate MEF. MEF, to put it shortly, let's you part a part of your class as [Import] and then say, "Go find a library in this directory which implements IGameEngine, load it, and fix up this variable." I implemented the first baby steps of using it late night and things were going well. That was, until I tested in under Linux.

MEF preview 8 as it stands does not work with mono/Linux. I'm not talking about a single specific issue that my code happens to trip, the built in examples don't even work. Examples bugs can be found here and here. One of them mentions this as won't be fixed until after the end of March at the earliest (post .Net 4 release). This leaves me with the unhappy situation of either:
  • Use MEF, and for at least the next two month have no chance of having a Linux version of Magecrawl
  • Don't use MEF, and either use another IoCish framework or wait until MEF works.
The only reasonable choice is the latter, punt on using MEF until the it can at least pretend to care about Linux/mono enough to get its built in examples working.

As a side note, this is why I test under Linux before each tech demo and whenever I'm about to make a large architectural change. If your writing something on one platform and expect it to work elsewhere, even if the library/language you're using claims to work there, testing early and often is a good idea.


Nolithius said...

Before you decide on the second course of action, weigh out the pros/cons of both:

On one hand, you keep the development momentum but make Linux players wait a month.

On the other hand, you are forced to do a rewrite and learn a new system, results of which will probably only emerge a month from now.

In any case, you're looking at having a Linux playable in a month's time, except under the first option, you avoid quite a bit of headaches and keep the momentum going!

donblas said...

I have a feeling that it's going to be a at least 2-3 months before it gets fixed, maybe more. Consider me somewhat cynical but I doubt this is first on their after initial release TODO list.

While it'd be nice to split out components using MEF now instead of waiting a few months, I still can do most of the work using interfaces and such.

From my shoes, punting on MEF and moving on to other issues is my way of keeping the momentum going. :)

georgek said...

I'm curious what specific problem MEF solves? I had a look at the documentation but I don't know .NET stuff, and they don't really say there in the introduction.

donblas said...

It makes it easy to have modularize your codebase.

Here's a quick example. Right now I have 4 components in Magecrawl, GameEngine, GameGUI, Utilities, and the Magecrawl executable. I also have an interface that that Magecrawl uses to talk to the GameEngine and convert that into a form that the GameGUI can show on the screen.

Inside of Magecrawl, I have a line that looks like:

IGameEngine engine = new PublicGameEngine();

Where IGameEngine is the public interface and PublicGameEngine is a concrete instance from GameEngine. This ties me to a specific instance of the engine, from a specific linked DLL. It makes moving stuff around more difficult.

With MEF I could mark PublicGameEngine
[Export typeof(IGameEngine)]

and inside Magecrawl

private IGameEngine m_engine;

Then when I call the Compose method (with some setup magic excluded for length), MEF will look in the directories I list for something that implements IGameEngine, create an instance of it, and set m_engine for it. The Magecrawl exec doesn't have to know anything about the GameEngine component at all, just the shared interface.

Make sense? If not, I can post later with some pictures and a longer explanation.

Nik Coughlin said...

Is there any specific reason for going with MEF rather than something like Unity? As I understand it MEF is more dynamically oriented and more suited for apps that need to be extended by other people rather than a framework that you're writing yourself.

donblas said...

I hadn't heard much about unity before now. It seems like it hasn't been updated for over a year, which makes me initially weary. MEF appealed to me since it's going to be part of the next .NET framework and I'm somewhat familiar due to some use at work.