Tuesday, August 31, 2010

Castle Monorail/Activerecord on Mono

I have had a heck of time trying to get Monorail working fully on Mono (2.4, 2.6, and even the latest tarballs). After weeks of sorting through code, I think I have finally figured out the solutions to the most common problems I've encountered:

1) Invalid casts in the form helper select generation. This has taken me quite awhile to track down, and the solution is simple enough that I thought I would blog about it to remember what I done in the future. The problem is with casting and the proxies for AR objects. The AR objects that are proxies, when used in a form helper select can sometimes generate an InvalidCastException if they have already been used. I ended up getting the source from GitHub and modifying the form helper itself in the ReflectionValueGetter. Here is the full GetValue method I used in the AbstractFormHelper.cs:

public override object GetValue(object instance)
   {
    try
    {
     try
     {
      return propInfo.GetValue(instance, null);
     } 
     catch (InvalidCastException)
     {
      propInfo = propInfo.ReflectedType.BaseType.GetProperty(Name);
      return propInfo.GetValue(instance, null);
     }
    }
    catch (TargetException)
    {
     var tempProp = instance.GetType().GetProperty(Name);

     if (tempProp == null)
     {
      throw;
     }

     return tempProp.GetValue(instance, null);
    }
   }

The new code is in the extra try/catch InvalidCastException block.  It merely gets the base type and tries to find the property there if it was an invalid cast (ie Instrument being cast as InstrumentProxy).  More can be found here.

2) Asynchronous actions do not work in mono (at least using the AspView engine and the ActiveRecord integration). I finally tracked this down due to the incorrect or null context being assigned on the End method. Luckily, the fix is VERY easy, especially considering how long it took me to track down. Merely do "HttpContext.Current = HttpContext" in the end method of the action, and it will correctly release the ActiveRecord session in the web module or in your custom methods to attach/release the session. More here.

2 comments:

  1. Hi Brian.
    I have never really tested AspView thoroughly in Mono, so it is great that you are finding these little issues, and fixing them.

    I suggest that you would consult with the users mailing list next time to bump into problems, someone might have already solved your problem.

    I would also ask that you'd be kind enough to commit your changes and fixes to a github fork and send a pull request (preferably with a unit test and donjon support ticket), so that the rest of the users will be able to easily enjoy your good work in the next version

    ReplyDelete
  2. Hi Ken,
    Thanks for your comment! The links ("More can be found here" and "More here") actually link to my posts on the mailing list. Not many have used mono thoroughly at all so I haven't been able to get a lot of feedback there, but I will definitely keep trying there first.

    I will work on getting the fix up on github and getting a ticket on donjon, thanks for giving me some direction on what exactly to do there.

    ReplyDelete