Mirror, Mirror

18 10 2012

Urgh… spent the last 4 hours tangling and untangling code using reflection on assemblies in C# and I think I’ve gone cross-eyed 😛

I’ve managed to do what I set out to do, which is to load a few assemblies and get all the classes with a certain attribute to them. It isn’t terribly hard to do I agree but the confusing part comes when I figured I can’t, easily, unload those assemblies because of the whole separation by AppDomain and not being able to unload specific assemblies within a single AppDomain without unloading the entire domain. Using Assembly.LoadFrom, by the way, load the input assembly quite well but into the AppDomain.CurrentDomain (I’ve tried to unload that during a test just to see what would happen… it made me laugh).

So, the code itself is fairly simple; load the assembly, get all types from that assembly with the particular attribute and then query the attribute for the required information.

[Test]
public void can_retrieve_attribute_properties()
{
  var assembly = Assembly.LoadFrom(File);
  var types =
    (from type in assembly.GetTypes()
    where Attribute.IsDefined(type, typeof(ContentImporterAttribute))
    select type).ToList();

  var first = types[0];
  var customAttributes =
    (from attribute in first.GetCustomAttributes(true)
    where attribute is ContentImporterAttribute
    select (ContentImporterAttribute)attribute).ToList();

  var importerAttribute = customAttributes[0];
  Assert.IsTrue(importerAttribute.FileExtensions.Contains(".edi"));
  Assert.AreEqual("EDI Importer", importerAttribute.DisplayName);
  Assert.AreEqual("TestProcessor", importerAttribute.DefaultProcessor);
}

There are a few caveats there; the first and most obvious one is that the test implies there is somewhere another assembly that has that particular attribute attached to a class in a very specific way (and in fact there is, I’ve made it myself for this test). The other little worry here is the fact that I’ve got no bound checking or indeed any null-assertions on referencing the first item in each list (I’m basically assuming that the first type is the one I’m looking for and that the first attribute on it is the one I’m looking for as well). But for me the biggest unknown here is the assembly loading behavior in a real-world context (which I shall test later) in regards to the whole AppDomain merry-go-round; after going through MSDN and StackOverflow for a couple of hours I did find some solutions but I’m not sure that the complexity involved with creating specialized domains is worth the trouble.

Anyway, even if this approach fails (can anyone guess what I’m trying to do? :P) I’ve got another way to go about the system which would work for sure but it does mean a bit more manual labor.

“…I cut down trees, I eat my lunch I go to the lavatory…”

Advertisements




TDDXNA

20 03 2011

Lots of letters…

As I’ve said before, using test driven development and unit tests on an established framework (XNA in this case) is fairly futile. I guess it can be done if I put my mind to it and lots of time to figure out how to mock every single aspect of the framework but I don’t think it’s worth it. In the end I have to trust that the framework does what it says it does and have my asserts, preconditions and postconditions act as the live tests for it; after all that’s what they’re there for.

Writting the sprite classes as data stores which describe the drawing/loading states of the actual images did prove to be the right course (so far anyway). It makes the code more natural to read and it allows me to apply these descriptions to multiple textures at once. The next module I’m going to throw myself at is the input and game commands, wonder how that’ll go?

Short post today, I’m sick and so is my little one…

“Lady Startdust sang his songs of darkness and dismay”





And I’m back!

16 03 2011

So, I’m not dead, not yet anyway; let’s just say I took a very looooong vacation. Which is a lie since I never take vacations and I’ve actually started full time work, but hey I’m allowed to dream.

The last time I’ve seen this blog it was actually still 2010 and I was writing tests for a timer class which is long been tested to death and it works… Honest… Trust me… Okay, alright, I’ll post the rest of the in the next couple of days once I reorganize and try to remember what the hell I was talking about. In the meanwhile I’m also glad to report that I’ve picked up two other projects to work on, both sort of have to do with Microsoft’s Dream.Build.Play (rather than Dream.Build.Debug which is a completely different thing altogether) and the upside of that is that I get to work with C# (which I have grown to love in the last few months) and XNA (which I have grown to like in the last two weeks). Well, being the lovable programmer that I am the first thing on my mind is, you guessed it, TDD!

And you know what, XNA is not the friedliest framework for tests as I’ve discovered, at least from what I’ve gathered by trying a few bits and reading up online. See the problem with a framework and the concept of Unit Tests is that I don’t think they mash together quite perfectly. Unit tests rely on nothing but the classes, frameworks force complience on everything they have and the kitchen sink (actually XNA isn’t that bad, I’ve seen worse, much much worse).

Let’s put things in perspective.

One of the projects in question to use XNA is a 2D platformer type thingy, which I won’t go into much detail since I’m not really at liberty to say much at the moment. I’ve been nabbed on Sprite duty. XNA comes with a lot of built in functionality for loading and drawing pretty 2D pictures via the ContentManager and the SpriteBatch objects and having a central object to hold all the nice data and functionailty will be really nifty; enter the mighty Sprite class. Let’s TDD!!

class TestNewSprite
{
  [TestMethod]
  public void name_is_NewSprite()
  {
    Assert.AreEqual("NewSprite", _sprite.Name); 
  }
}

Wooh, so many things that break on that it isn’t even funny. For the rest of it you’ll have to imagine me building the code backwards.

class TestNewSprite
{
  public TestNewSprite()
  { 
    _sprite = new Sprite("NewSprite"); 
  }

  [TestMethod]
  public void name_is_NewSprite()
  { 
    Assert.AreEqual("NewSprite", _sprite.Name); 
  }

  private Sprite _sprite;
}

Alright, I know the drill; create the class, create the fields and watch everything go green. Now what?

My first thought was a Sprite needs an image. Basic right? I mean, the whole point of it is to wrap a texture and describe how to draw it with extra data… Wrong! This is basically where I hit a brick wall. A Texture2D object requires the XNA framework to load, meaning I would need start fiddling around with mocks and manually instantiating the parts of the framework which I need. While these things are possible, and in fact have been done by a couple of other people on the ‘net, it just doesn’t strike me as a unit test, intergration test – yes, but not a unit test. So after some thought and talking to myself while doing the dishes I’ve decided to change my perspective on the problem.

I’ll TDD my Sprite class as a data set which describe the drawing behaviour to apply on a texture. The class will hold a reference to a texture which will be created by a ContentManager object but I’ll not test that particular functionality, I’ve got to trust XNA that it works right?

I’ll most likely wrap XNA’s concept of a ContentManager in my own custom object which will automate the loading of a texture using the Sprite class data. And as for drawing; same thing. I’ll wrap the SpriteBatch in an object which will know how to use the Sprite, SpriteMap and whatever else I’ll think about and joy to the world. Unit tests will ensure not only that I only have the data I need but that all my assumptions about manipulating it [like scaling, moving, etc.] will be correct.

Since I haven’t yet tried it I don’t know if it’ll work but I suspect that it will. I’ll write up a self-review tomorrow after the first attempt.

“Though I do like breaking femurs, You can count me with the dreamers”