Archive for the ‘code snippets’ Category

Slower than Reflection; meet StackTrace

Monday, October 13th, 2008

I was enter­tain­ing the idea of con­tex­tual com­po­nents that would act dif­fer­ently depend­ing on who called them. System.Diagnostics.StackTrace is the class that allows you to tra­verse the call stack, and see who called your method. There’s one catch though – it is painfully slow. And by painfully, I mean this:

StackTrace

Those two meth­ods are by no means com­pa­ra­ble in regard of what they’re doing. They are mere exam­ples of sim­ple tasks: one involv­ing Reflec­tion, and one involv­ing Stack­Trace. The fact that the dif­fer­ence in per­for­mance is nearly two orders of mag­ni­tude, should make you think twice before you go down the Stack­Trace path. Espe­cially con­sid­er­ing the fact, that you can’t really cache it.

Tech­no­rati Tags: , ,

Testing collections with NUnit

Saturday, August 2nd, 2008

How do you test col­lec­tions for equal­ity of their ele­ments? I often used to write my own cus­tom assert for that, some­thing like:

public void AssertCollectionElementsAreEqual<T>(IEnumerable<T> expected, IEnumerable<T> actual)
{
    var first = expected.GetEnumerator();
    var second = actual.GetEnumerator();
    int count = 0;
    while(first.MoveNext())
    {
        if(second.MoveNext())
        {
            Assert.AreEqual(first.Current,second.Current);
        }
        else
        {
            throw new AssertionException(string.Format("Collection has less elements than expected: {0}", count));
        }
        count++;
    }
    if(second.MoveNext())
    {
        throw new AssertionException(string.Format("Collection has more elements than expected."));
    }
}

I thought it’s just plain to com­mon task to not be included in the frame­work itself, so I read the man­ual, and I found CollectionAssert.AreEqual() method that does exactly that.

Then Char­lie Poole, made me real­ize there is even sim­pler way.

using System.Collections.Generic;
using NUnit.Framework;
 
namespace NUnitAreEqualSample
{
    [TestFixture]
    public class CollectionsEqualitySampleTests
    {
        [Test]
        public void DifferentTypesOfCollectionsShoudBeEqualIfElementsAreEqual()
        {
            var list = new List<string> {"foo", "bar"};
            var array = new[] {"foo", "bar"};
            Assert.AreEqual(list, array);//notice this
        }
    }
}

This pro­duces fol­low­ing result:

nunit_areEqual_passed

Sim­ple Assert.AreEqual() does the job. Sweet.

Tech­no­rati Tags: , ,

On generics limitations

Wednesday, May 28th, 2008

I wish gener­ics in C# were more pow­er­ful. Why this is not legal?

public class ServiceHost<TService> : ServiceHost where TService : class
{
    public ServiceEndpoint AddServiceEndpoint<TServiceInterface>(Binding binding, string address)
        where TService : TServiceInterface
    {
        return AddServiceEndpoint(typeof(TServiceInterface), binding, address);
    }
}

Tech­no­rati Tags:

Can you spot a bug?

Saturday, May 24th, 2008

Can you spot a bug here?

Took me 20 min­utes to find it.smile_whatchutalkingabout

 

private List<string> GetLanguages(string path)
{
    var languages = new List<string>();
    if(File.Exists(path))
    {
        using(var reader = new StreamReader(path,_encoding))
        {
            var dscReader = new DscReader(reader);
            while(dscReader.Read())
            {
                string language = dscReader.Item.Language;
                if (!string.IsNullOrEmpty(language) && !language.Contains(language))
                    languages.Add(language);
            }
        }
    }
    return languages;
}
Tech­no­rati Tags:

Simplifying Rhino.Mocks, Round III: kinds of mocks

Thursday, April 24th, 2008

My last two posts regard­ing Rhino.Mocks, attracted quite a lot of atten­tion. Focus­ing on solu­tion I pro­posed for lim­it­ing com­plex­ity around cre­ation dif­fer­ent kinds of mocks, one thing was pointed out by few peo­ple as not the best solu­tion. Ayende called it "in your face! API design", that is stat­ing the kind of mock you want to cre­ate explic­itly, via method parameter.

I don't think that doing it via method name is any less explicit, but let's not go there. Instead, let's think for a while — why do we need 4 kinds of mocks anyway?

All dif­fer­ences boil down to one thing — how the mock han­dles unrecorded calls:

  • Strict­Mock (_repo.CreateMock over­loads), any unex­pected call results in excep­tion being thrown.
  • Dynam­ic­Mock (_repo.DynamicMock over­loads), any unex­pected call returns default(T), where T is return type, that is null or 0 for value types.
  • Par­tial­Mock (_repo.PartialMock over­loads), this works only for classes and any unex­pected call is not inter­cepted but for­warded to the actual method of that class.
  • Stub (_repo.Stub), this is sim­i­lar to Dynam­ic­Mock with addi­tion, that if you assign a value to a prop­erty, it remem­bers that value.

Those are all very impor­tant dif­fer­ences but I'd say quite sub­tle. Sub­tle to a point, that I am will­ing to agree that spec­i­fy­ing them upfront either via explic­itly named cre­ation method, or via explicit para­me­ter is throw­ing "in your face!" deci­sions that you shouldn't have to be con­cerned about at this point.

Morten Lyhr noticed this as well, and he sug­gested the fol­low­ing solution:

public class LoginPresenterFixture
{
   private MockRepository _mockRepository;
   private LoginPresenter _loginPresenter;
   private LoginView _loginView;
   [SetUp]
   public void Init()
   {
      _mockRepository = new MockRepository();
      _loginView = _mockRepository.DynamicMock<LoginView>();
      CreateLoginPresenter();
   }
   private void CreateLoginPresenter()
   {
      _loginPresenter = new LoginPresenter(_loginView);
   }
   [Test]
   public void Strict_Test_Not_As_Often_Used()
   {
      //Override default mock kind
      _mockRepository.StrictMockBehaviour(_loginView);//this is important
      using (_mockRepository.Record())
      {
         Expect.Call(_loginView.ShowView);
      }
      using (_mockRepository.Playback())
      {
         _loginPresenter.Show();
      }
   }
}

It's some way of deal­ing with it but it still requires you to explic­itly assign behav­ior to mock object.

It's still incor­rect level of gran­u­lar­ity though: instead of class level (dif­fer­ent class per dif­fer­ent mock kind) we now deal with it on object level (dif­fer­ent kind per object).

I'd how­ever move it yet one step fur­ther, to method level (dif­fer­ent kind per method).

It might look some­thing like this:

   [Test]
   public void Strict_Test_Not_As_Often_Used()
   {
      using (_mockRepository.Record())
      {
         Expect.Call(_loginView.ShowView);
         //Decide what to do with unexpected calls:
         Expect.For(_loginView).NothingElse();//this is important
      }
      using (_mockRepository.Playback())
      {
         _loginPresenter.Show();
      }
   }

Again, dif­fer­ence is very sub­tle, but impor­tant: instead of explic­itly decid­ing about kind of mock, we decide about what to do about unex­pected calls, which is more nat­ural and closer to the actual prob­lem. Dif­fer­ent kinds of mocks, are just pro­posed solu­tions. The 'kind' is no longer a prop­erty of the mock object.

It also makes it eas­ier to start with mock­ing frame­work: deci­sion about what to do about unex­pected calls is not thrown at your face at the very first lines, hid­den behind terms like "Par­tial" or "Dynamic". Instead you make that deci­sion explic­itly (and this time it's a good thing) in last respon­si­ble moment that is in the actual test.

Tech­no­rati Tags: , , ,

Simplifying Rhino.Mocks

Monday, April 21st, 2008

[UPDATE]: Exam­ple code is updated. I real­ized that Kind.Multi is not needed, since you can infer that from passed para­me­ters (when ctorArgs are present, user obvi­ously wants to cre­ate Mul­ti­Mock). I also changed default Kind to Relaxed, since this is the most com­mon one.

Ayende wrote today about his ideas for new ver­sion of Rhino.Mocks. I like the new syn­tax (looks sim­i­lar to what MoQ offers), but there's one more change I'd like to see.

Here's the list of all meth­ods of Mock­Repos­i­tory, used to cre­ate some kind of mock:

 

public T CreateMock<T>(params object[] argumentsForConstructor);
public object CreateMock(Type type, params object[] argumentsForConstructor);
public T CreateMockWithRemoting<T>(params object[] argumentsForConstructor);
public object CreateMockWithRemoting(Type type, params object[] argumentsForConstructor);
public T CreateMultiMock<T>(params Type[] extraTypes);
public object CreateMultiMock(Type mainType, params Type[] extraTypes);
public T CreateMultiMock<T>(Type[] extraTypes, params object[] argumentsForConstructor);
public object CreateMultiMock(Type mainType, Type[] extraTypes, params object[] argumentsForConstructor);
public T DynamicMock<T>(params object[] argumentsForConstructor);
public object DynamicMock(Type type, params object[] argumentsForConstructor);
public T DynamicMockWithRemoting<T>(params object[] argumentsForConstructor);
public object DynamicMockWithRemoting(Type type, params object[] argumentsForConstructor);
public T DynamicMultiMock<T>(params Type[] extraTypes);
public object DynamicMultiMock(Type mainType, params Type[] extraTypes);
public T DynamicMultiMock<T>(Type[] extraTypes, params object[] argumentsForConstructor);
public object DynamicMultiMock(Type mainType, Type[] extraTypes, params object[] argumentsForConstructor);
public static T GenerateStub<T>(params object[] argumentsForConstructor);
public static object GenerateStub(Type type, params object[] argumentsForConstructor);
public T PartialMock<T>(params object[] argumentsForConstructor) where T : class;
public object PartialMock(Type type, params object[] argumentsForConstructor);
public T PartialMultiMock<T>(params Type[] extraTypes);
public T PartialMultiMock<T>(Type[] extraTypes, params object[] argumentsForConstructor);
public object PartialMultiMock(Type type, params Type[] extraTypes);
public object PartialMultiMock(Type type, Type[] extraTypes, params object[] argumentsForConstructor);
public T Stub<T>(params object[] argumentsForConstructor);
public object Stub(Type type, params object[] argumentsForConstructor);

26 meth­ods includ­ing 2 sta­tic meth­ods (most of them in 2 fla­vors: generic and 1.1-like). I guess that's a lot. I can imag­ine this can be a lit­tle over­whelm­ing for new users.

I under­stand that tear­ing inter­face of Mock­Repos­i­tory would not be the best idea, but I think that cre­at­ing a Facade to it might sim­plify things a lot.

public class MockRepositorySlim
{
    private static readonly Dictionary<Kind, Func<MockRepository, Type, object[], Type[], object>> _mockMethods =
        new Dictionary<Kind, Func<MockRepository, Type, object[], Type[], object>>(9)
            {
                {Kind.Relaxed,(r, t, cp, et) => et.Length > 0 ? r.DynamicMultiMock(t, et, cp) : r.DynamicMock(t, cp)},
                {Kind.Strict, (r, t, cp, et) => et.Length > 0 ? r.CreateMultiMock(t, et, cp) : r.CreateMock(t, cp)},
                {Kind.Stub, (r, t, cp, et) => r.Stub(t, cp)},
                {Kind.Partial,(r, t, cp, et) => et.Length > 0 ? r.PartialMultiMock(t, et, cp) : r.PartialMock(t, cp)},
                {Kind.Strict | Kind.WithRemoting, (r, t, cp, et) => r.CreateMockWithRemoting(t, cp)},
                {Kind.Relaxed | Kind.WithRemoting, (r, t, cp, et) => r.DynamicMockWithRemoting(t, cp)}
            };
 
    private readonly MockRepository _repo = new MockRepository();
 
    public TTypeToMock Mock<TTypeToMock>()
    {
        return Mock<TTypeToMock>(Kind.Relaxed, new Type[0], new object[0]);
    }
 
    public TTypeToMock Mock<TTypeToMock>(Kind mockKind)
    {
        return Mock<TTypeToMock>(mockKind, new Type[0], new object[0]);
    }
 
    public TTypeToMock Mock<TTypeToMock>(Kind mockKind, params object[] ctorArgs)
    {
        return Mock<TTypeToMock>(mockKind, new Type[0], ctorArgs);
    }
 
    public TTypeToMock Mock<TTypeToMock>(Kind mockKind, params Type[] extraTypes)
    {
        return Mock<TTypeToMock>(mockKind, extraTypes, new object[0]);
    }
 
    public TTypeToMock Mock<TTypeToMock>(Kind mockKind, Type[] extraTypes, params object[] ctorArgs)
    {
        if (extraTypes == null) throw new ArgumentNullException("extraTypes");
        if (ctorArgs == null) throw new ArgumentNullException("ctorArgs");
 
        if (mockKind == Kind.WithRemoting)
            mockKind &= Kind.Strict;
        else if (!_mockMethods.ContainsKey(mockKind))
        {
            if ((mockKind & Kind.WithRemoting) != 0)
                throw new ArgumentException("This kind of mock does not support remoting.");
            throw new ArgumentException("Invalid mock kind.", "mockKind");
        }
        //NOTE: possibly with lock in this call
        var mock = (TTypeToMock) _mockMethods[mockKind](_repo, typeof (TTypeToMock), ctorArgs, extraTypes);
        return mock;
    }
}
internal static class KindExtensions
{
    public static bool IsSet(this Kind kind, Kind value)
    {
        return (kind & value) == 0;
    }
}
 
 
[Flags]
public enum Kind
{
    Strict=0,
    WithRemoting=1,
    Relaxed=2,
    Stub=4,
    Partial=8
}

Now we have only 5 meth­ods, 4 of which call the 5th one. I guess that's sim­pler solu­tion. Is it any better?

Tech­no­rati Tags: , ,

Beautiful code

Friday, April 18th, 2008

Ok, maybe this title is a lit­tle bit too catchy. How­ever, I sim­ply love the expres­sive­ness of this lit­tle piece of code I wrote today.

   1:          public bool RegisterAll( Assembly assembly, Func<object, bool> isValidMessage )
   2:          {
   3:              if( assembly == null )
   4:              {
   5:                  throw new ArgumentNullException( "assembly" );
   6:              }
   7:              if( isValidMessage == null )
   8:              {
   9:                  throw new ArgumentNullException( "isValidMessage" );
  10:              }
  11:              var messages = from t in assembly.GetTypes()
  12:                             where t.HasAttribute<MessageAttribute>() &&
  13:                                   isValidMessage( t )
  14:                             select t;
  15:              return messages.All( Register );
  16:          }

 

Tech­no­rati Tags: ,

I want that in C# 4.0

Friday, March 28th, 2008
I've been play­ing with Boo recently and I find it to be very pow­er­ful lan­guage. One lit­tle thing I like par­tic­u­larly is, that I can do this:
name = "Krzysztof"
print "Hello, ${name}, on the beautiful day of ${date.Today}"
And get this:
boo
Can I please have this in C# 4.0?
Tech­no­rati Tags: , ,

Mocking with Moq and Rhino.Mocks

Thursday, March 27th, 2008

Last week I've read quite a few new blog­posts about Moq mock­ing frame­work. I had looked at it once, when it was first released, but I didn't find it inter­est­ing back then. Now that ver­sion 2.0 was released I decided to give it a go once again.

Here's very sim­ple model I created:

model

It's a class with one method that uses helper object to obtain a value and pos­si­bly raise an event.

Here's the whole code:

public interface IHelper
    {
        int Param { set; }
        string SomeMethod();
    }
    public class MyClass
    {
        public MyClass(IHelper helper)
        {
            Helper = helper;
        }
 
        public IHelper Helper { set; private get; }
 
        public event EventHandler MyEvent = delegate { };
 
        public void DoSomething(int parameter)
        {
            Helper.Param = parameter;
            string result = Helper.SomeMethod();
            if (result != null)
                MyEvent(null, EventArgs.Empty);
        }
    }

Now, to the fun part:

Let's see how we can ver­ify that when SomeMethod returns null, MyEvent is indeed not raised. First with Rhino.Mocks

   1:          [Test]
   2:          public void DoDomething_should_NOT_raise_MyEvent_when_helperSomeMethod_returns_null_Rhino()
   3:          {
   4:              var helper = _mocks.CreateMock<IHelper>();
   5:              var subscriber = _mocks.CreateMock<IEventSubscriber<EventArgs>>();
   6:              using (_mocks.Record())
   7:              {
   8:                  Expect.Call(helper.Param = 3);
   9:                  Expect.Call(helper.SomeMethod()).Return(null);
  10:                  DoNotExpect.Call(() => subscriber.Method(null, EventArgs.Empty));
  11:              }
  12:              using (_mocks.Playback())
  13:              {
  14:                  var sut = new MyClass(helper);
  15:                  sut.MyEvent += subscriber.Method;
  16:                  sut.DoSomething(3);
  17:              }
  18:          }

18 lines of code (you could cut that down to 13 sim­ply by using Replay­All() instead of Record() and Ver­i­fyAll in Tear­Down method instead of Play­back, but I pre­fer it this way. My code is clean and quite well serves as doc­u­men­ta­tion: Espe­cially thanks to explicit usage of DoNotExpect.

The only awk­ward thing, is that whereas in both Expect call, I insert bare calls, in DoNotExpect.Call I had to use lambda. It's a small inconsistency.

Now how would the same test look like with Moq?

   1:          [Test]
   2:          public void DoDomething_should_NOT_raise_MyEvent_when_helperSomeMethod_returns_null_Moq()
   3:          {
   4:              var helper = new Mock<IHelper>(MockBehavior.Strict);
   5:              var subscriber = new Mock<IEventSubscriber<EventArgs>>(MockBehavior.Strict);
   6:              helper.Expect(h => h.Param = 3);
   7:              helper.Expect(h => h.SomeMethod()).Returns((string)null);
   8:   
   9:              var sut = new MyClass(helper.Object);
  10:              sut.MyEvent += subscriber.Object.Method;
  11:              sut.DoSomething(3);
  12:          }

12 lines includ­ing one empty to visu­ally divide setup part from test­ing part. Nice. There's how­ever one BIG prob­lem with this code: it won't com­pile. As I said ear­lier, You can't have assign­ment in Expres­sions, and that's what Moq is using, so if you want to set some prop­er­ties on your mock… well — you're out of luck. I also don't like the fact that I have to cast null, to string. This seems redun­dant, but it's only a small annoyance.

Big­ger prob­lem is that I can't explic­itly state that I expect MyEvent not to be raised.

Another thing, I couldn't find a way to get hold of event raiser. I guess it's just not there, so if you want to test events… you're out of luck too.

Moq is inter­est­ing project for sure, it's sim­ple (sim­plis­tic) syn­tax made me think, about how com­pli­cated Rhino.Mocks became. Sure it's orders of mag­ni­tude more pow­er­ful, but some uni­fi­ca­tion of inter­faces, even for a price of break­ing some old code would be highly desired. I can imag­ine that for a new­comer cur­rent learn­ing curve may seem steep. Espe­cially the fact of using sta­tic classes makes API much less discoverable.

So I will stick to Rhino.Mocks, as it Moq is still to sim­ple for seri­ous use, but I'm glad it's there. It brings some fresh ideas to the table, and there's noth­ing bet­ter than a lit­tle competition.

Tech­no­rati Tags: , , ,

Building dynamically look up table of classes with LINQ and Reflection

Wednesday, March 26th, 2008

Here's the prob­lem: Hav­ing some ID, get a new instance of some class cor­re­spond­ing to this ID. All classes imple­ment the same com­mon inter­face (by which we will use them).

So we need to be able to write some­thing like:

public IMessage DoSomethingWithMessage(Id id)

{

    IMessage message = MessageFactory.CreateMessage(id);

    message.DoSomething();

}

Now, how to actu­ally imple­ment Mes­sage­Fac­tory, know­ing that it needs to be really fast, and with­out hav­ing to explic­itly change its imple­men­ta­tion when new mes­sages are added, Ids change and so on? And how to bind IDs to Messages?

Here's my idea for the solu­tion, and com­ments and improve­ments are more than welcome.

Each Mes­sage has its ID known before­hand, so it seems log­i­cal that the only place where this knowl­edge is kept should be the class itself. Now, I could define this ID as const, or sta­tic read­only field in each class, but this seems a lit­tle bit awk­ward to me.

First, I don't gain any­thing by it, I can't enforce a class to have a sta­tic field for once, and it doesn't seem to belong there. It's not used any­where else than as a way to iden­tify a class that should be instan­ti­ated in this one place, so it's more like meta­data on a class, rather than actual class' data. That's why I declared IdAt­tribute class that I dec­o­rate each Mes­sage class with.

Next thing: actual reg­is­tra­tion. How to have the cake (have all the types reg­is­tered prop­erly) and eat it (not hav­ing to change Mes­sage­Fac­tory' imple­men­ta­tion each time I change a mes­sage). Since I'm already using reflec­tion to get to each mes­sage' Id, it seems rea­son­able to hit two birds with one stone, and get the types via reflec­tion as well. Finally I came up with this LINQ query:

private static readonly IDictionary<int, MessageCreator> messages =

    (from t in Assembly.GetExecutingAssembly().GetTypes()

     where t.IsClass && !t.IsAbstract && t.Implements<IMessage>() && t != typeof (EmptyMessage)

     select t).ToDictionary(t => t.Attribute<IdAttribute>().Id, c => c.GetCreator());

Please ignore Mes­sage­Cre­ator and other cus­tom exten­sion meth­ods. We'll get to them in a second.

Another prob­lem is the actual instan­ti­a­tion. As I said, it needs to be very fast, so based on Oren's recent study, I decided to go where the drag­ons live and use Dynam­icMethod. It adds lit­tle over­head when the pro­gram starts to build meth­ods, but it hap­pens before the pro­gram gets under heavy fire of requests, so it's fine.

I cre­ated del­e­gate dec­la­ra­tion for my cre­ation methods

public delegate IMessage MessageCreator();

And then the actual method for cre­at­ing cer­tain type of Mes­sage (Get­Cre­ator exten­sion method from above LINQ query).

public static MessageCreator GetCreator(this Type type)

{

    var method = new DynamicMethod("Create" + type.Name, type, new Type[0]);

    ILGenerator gen = method.GetILGenerator();

    ConstructorInfo ctor = type.GetConstructor();

    gen.Emit(OpCodes.Newobj, ctor);

    gen.Emit(OpCodes.Ret);

    return (MessageCreator)method.CreateDelegate(typeof (MessageCreator));

}

Get­Con­struc­tor is exten­sion method that gets default constructor.

Here's the entire code:

using System;

using System.Collections.Generic;

using System.Linq;

using System.Reflection;

using System.Reflection.Emit;

 

 

namespace Creation

{

    class Program

    {

        static void Main(string[] args)

        {

            IMessage message = MessageFactory.CreateMessage(1);

            Console.WriteLine(message.Write());

            IMessage empty = MessageFactory.CreateMessage(-1);

            Console.WriteLine(empty.Write());

        }

    }

 

    public class MessageFactory

    {

        private static readonly IDictionary<int, MessageCreator> messages =

            (from t in Assembly.GetExecutingAssembly().GetTypes()

             where t.IsClass && !t.IsAbstract && t.Implements<IMessage>() && t != typeof(EmptyMessage)

             select t).ToDictionary(t => t.Attribute<IdAttribute>().Id, c => c.GetCreator());

 

        private static readonly IMessage empty = new EmptyMessage();

 

        public static IMessage CreateMessage(int id)

        {

            if (messages.ContainsKey(id))

                return messages[id]();

            return empty;

        }

    }

 

    public delegate IMessage MessageCreator();

 

    public interface IMessage

    {

        string Write();

    }

    

    [Id(1)]

    public class Message1:IMessage

    {

        public string Write()

        {

            return ToString();

        }

    }

 

    [Id(2)]

    public class Message2:IMessage

    {

        public string Write()

        {

            return ToString();

        }

    }

 

 

    public class EmptyMessage:IMessage

    {

        public string Write()

        {

            return ToString();

        }

    }

 

    [AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]

    public sealed class IdAttribute : Attribute

    {

        private readonly int _id;

        public IdAttribute(int id) {

            _id = id;

        }

 

        public int Id

        {

            get { return _id; }

        }

    }

 

    public static class TypeExtensions

    {

        public static bool Implements<IInterface>(this Type type)

        {

            return type.GetInterfaces().Contains(typeof (IInterface));

        }

        public static TAttribute Attribute<TAttribute>(this Type type) where TAttribute:Attribute

        {

            return (TAttribute)type.GetCustomAttributes(typeof (TAttribute), false).Single();

        }

        public static ConstructorInfo GetConstructor(this Type type)

        {

            return type.GetConstructors().Single(c => c.IsPublic && c.GetParameters().Count() == 0);

        }

 

        public static MessageCreator GetCreator(this Type type)

        {

            var method = new DynamicMethod("Create" + type.Name, type, new Type[0]);

            ILGenerator gen = method.GetILGenerator();

            ConstructorInfo ctor = type.GetConstructor();

            gen.Emit(OpCodes.Newobj, ctor);

            gen.Emit(OpCodes.Ret);

            return (MessageCreator)method.CreateDelegate(typeof (MessageCreator));

        }

    }

}

There are few things I don't like about this solu­tion however.

Con­ven­tions. It's a con­ven­tion that each Mes­sage must have Id attribute, with unique value, and it's a con­ven­tion that each must have default pub­lic con­struc­tor. In the actual code Get­Con­struc­tor and Attribute<TAttribute> meth­ods throw descrip­tive excep­tions when those con­ven­tions aren't met, but it hap­pens at run­time, not dur­ing compilation.

Reflec­tion. It seems to be rea­son­able choice, but if there was some other solution…

Any­way, I'm open for sug­ges­tions on how to improve/change that.

Tech­no­rati Tags: , , ,