MEF, The DLR, IronRuby, and the Web

Uncategorized 6 Comments »

After seeing Glenn Block talk about MEF in phoenix last week, I began to write a demo for work.

We have a pretty big pain point in our flagship product at work and I think that MEF would be a great way to alleviate that pain. Specifically, I would love to be able to just simply script that part of the application.

Enter Nicholas Blumhardt’s post about hosting IronRuby parts in MEF.

Nick has done quite a great job getting this to work. I had to update his code very little to use the latest version of MEF and the DLR.

Specifically, I had to add the “ExportTypeIdentity” metadata value to all ruby objects being exported.

  1: def self.export(cname, attrs={})
  2:
  3:   if cname.is_a?(Module)
  4:     include cname
  5:   end
  6:
  7:   attrs["ExportTypeIdentity"]=contract_name(cname)
  8:
  9:   export_attr(cname, attrs) do
 10:     self
 11:   end
 12: end
 13:
 14: def self.create_export_def(cname, attrs, accessor)
 15:   metadata = System::Collections::Generic::Dictionary[System::String,System::Object].new
 16:   attrs.each{|key, value| metadata.add key, value}
 17:   RubyExportDefinition.new(contract_name(cname), metadata, accessor)
 18: end

This works freaking great in my little test console app. But, it will not work for some reason in a web context. And as luck would have it, our flagship product is a web application. :(

This is the error I can’t seem to get around.

1) The export ‘ClassLibrary1.IContract’ is not assignable to type ‘ClassLibrary1.IContract’.

Has anyone made this work?

Download a demo here

It Finally Happened

Cars No Comments »

The same story that bugs everyone…

Minivan doing 45 MPH in the left lane, I decide to let the Hemi roar into the car pool lane and pass her. As soon as I can see in front of her and, mind you, way too late in my Hemi’s power band to do anything about it, I see a mobile radar van!

It now makes all too much sense why someone would poke around in the fast lane.

In AZ, they can’t ticket you if they can’t ID you so, dangerously, I quickly turn my head 180 degrees opposite of the van. I wipe my brow and silently congratulate myself on the quick thinking and avoiding the ‘tard ticket.

After the pass, no sooner that I get back in the left lane, what do I see hauling ass (for a Ford) up to me in the rear-view? Yup! An AZ DPS patrol car. I’m going the speed limit and keeping one eye ahead and one in the rear-view mirror. What a sight that must have been for the minivan! I was just sweating for the best. I’m sure you can guess what happened next.

Far right, on the shoulder; car off, windows down, radio off, hands on the wheel, just accepting my fate. He didn’t even ask the requisite, "Do you know why I pulled you over?". I honestly wasn’t sure I would know even if he did ask. Was it for accelerating way quicker than the average car? Was is it plain old speeding?

He asked for my papers and left me sitting there for about 20 minutes. I don’t have any warrants, and I don’t know why but, I was waiting for backup to arrive and haul me to jail. I guess the mind tends to wander when bored.

He finally came back to the car and told me that he was going to give me a break, from a $400 ticket for driving in the car pool lane, and just write the ticket for "Failure to obey a traffic control sign". This charge is significantly cheaper. Clocking in a $130 or traffic school.

Thanks, cool cop!

After more than 3 years of ownership, I’ve finally managed to get a ticket. And it wasn’t for speeding!!!

Legacy ASP.NET == typeof(Satan)

Development 3 Comments »
        'clean up any previous data if present
        'start with the checkboxes
        Dim tblControl As HtmlTable = CType(checkBoxes.Controls(0), HtmlTable)
        For Each control As System.Web.UI.Control In tblControl.Controls
            If (TypeOf control Is System.Web.UI.HtmlControls.HtmlTableRow) Then
                For Each rowControl As System.Web.UI.Control In control.Controls
                    If (TypeOf rowControl Is System.Web.UI.HtmlControls.HtmlTableCell) Then
                        For Each cellControl As System.Web.UI.Control In rowControl.Controls
                            If (TypeOf cellControl Is System.Web.UI.WebControls.CheckBox) Then
                                Dim chkBox As System.Web.UI.WebControls.CheckBox = CType(cellControl, System.Web.UI.WebControls.CheckBox)
                                chkBox.Checked = False
                            End If
                        Next
                    End If
                Next
            End If
        Next

My DIY Paint Job

DIY No Comments »



Next Day

Originally uploaded by cmartinbot

I actually did a pretty good job. :P

Javascript Reflection

Development No Comments »

I’m not happy with the json.js script from http://json.org so I’m going to write my own.

For future reference, I’m posting the start of my object reflection class.

if(typeof Caliberweb == 'undefined') var Caliberweb = {};
(function(){
    if(typeof Caliberweb.Reflection == 'undefined') {
        Caliberweb.Reflection = {
            getMembers: function(obj,match){
                var bucket = [];
                for(var i in obj){
                    if(match(i)) bucket.push(i);
                }
                return bucket;
            },
            GetProperties: function(obj){
                return this.getMembers(obj, function(member){
                    return typeof member != 'function';
                })
            },
            GetMethods: function(obj){
                return this.getMembers(obj, function(member){
                    return typeof member == 'function';
                });
            }
        }
    }
})();

February 20th, 2009

EOD Journal No Comments »
  • If jQuery was a living being, it would have died today.
  • Kent’s jaw is full of puss. I’ve got to get him to the vet tomorrow. Hopefully, it’s just a nasty tick that he scratched off.
  • I don’t think I have any friends left that don’t suck.
  • I’m drinking tonight. Damn you, jQuery! :)

February 19th, 2009

EOD Journal 1 Comment »
  • jQuery makes my job easier
  • Hyped up on the CrystalTech Dashboard
  • Mowed the lawn/weeds
  • Realized that reel mowers suck ass at cutting weeds.
  • Happy that the grass is aggressively taking over the weeds though.
  • Kent loved the car ride to QT.
  • Haven’t drank in a couple of days and I feel pretty damn good.

ILocalData Again

Development No Comments »

Just a random ‘ah-hah’ momentary update on the last post.

EDIT: After further refactoring, I’m done….for now.

You can download the code here.

February 18th, 2009

EOD Journal No Comments »
  • Woke up without water in the house. They turned it off without warning yesterday. No shower. :(
  • Started to implement dashboard functionality for the crystaltech.com control panel.
  • Extremely proud of the new CrystalTech.Menus code.
  • Paid the water bill
  • Started my blog again after a long hiatus
  • Started to brainstorm new design for Airflow Innovations Corp website.
  • Need a new driveshaft for the Magnum. Probably going with a custom piece from Dicks Drive Shaft.

Cool ILocalData Implementation

Development 1 Comment »

I’ve always been impressed with Ayende’s LocalData class. I like Ritesh Rao’s vision of local data even more. I loved how he gives the option of application, session, and thread storage. But, I feel like those implementations leave something to be desired from a consumers perspective. So, I’ve come up with a base interface that is inspired by both of the above projects. It also defines an abstract class so I can create new implementations whenever I need to.

The ILocalData interface:

public interface ILocalData
{
    object this[object key] { get; set; }
    T Get(object key);
    bool TryGet(object key, out T value);
    T Set(object key, T value);
    void Add(object key, object value);
    void Remove(object key);
    void Remove(params object[] keys);
    bool Contains(object key);
    void Clear();
}

The IDataBucket interface:

public interface IDataBucket : IEnumerable
{
    object this[object key] { get; set; }
    bool ContainsKey(object key);
    void Remove(object key);
    void Clear();
    void Add(object key, object value);
    bool UseSynchLock { get; set; }
}

The entry point and abstract class:

public class LocalData : BucketData
{
    public LocalData(IDataBucket bucket)
        : base(bucket)
    {}

    public LocalData(Func<IDataBucket> bucketProvider)
        : base(bucketProvider)
    {}
}

public abstract class BucketData : ILocalData, IEnumerable
{
    private static readonly object lockInstance = new object();
    private readonly Func<IDataBucket> bucketProvider;

    protected BucketData(IDataBucket bucket)
        : this(() => bucket)
    {}

    protected BucketData(Func<IDataBucket> bucketProvider)
    {
        this.bucketProvider = bucketProvider;
    }

    public IDataBucket Bucket
    {
        get { return bucketProvider(); }
    }

    public object this[object key]
    {
        get { return Do(() => Bucket[key.ToString()]); }
        set { Do(() => Bucket[key.ToString()] = value); }
    }

    public IEnumerator GetEnumerator()
    {
        return Bucket.GetEnumerator();
    }

    public T Get<T>(object key)
    {
        return Do(() =>
                      {
                          T value;
                          TryGet(key, out value);
                          return value;
                      });
    }

    public bool TryGet<T>(object key, out T value)
    {
        value = default(T);
        object data = Bucket[key.ToString()];

        if (data == null)
            return false;

        if (data is T)
        {
            value = (T) data;
            return true;
        }

        return false;
    }

    public T Set<T>(object key, T value)
    {
        return Do(() =>
                      {
                          Bucket[key.ToString()] = value;
                          return value;
                      });
    }

    public void Add(object key, object value)
    {
        Set(key, value);
    }

    public void Remove(object key)
    {
        if (Contains(key))
            Do(() => Bucket.Remove(key.ToString()));
    }

    public void Remove(params object[] keys)
    {
        foreach (object key in keys)
        {
            Remove(key);
        }
    }

    public bool Contains(object key)
    {
        return Do(() => Bucket[key.ToString()] != null);
    }

    public void Clear()
    {
        Do(() => Bucket.Clear());
    }

    private V Do<V>(Func<V> function)
    {
        if (Bucket.UseSynchLock)
        {
            lock (lockInstance)
            {
                return function();
            }
        }

        return function();
    }

    private void Do(Action action)
    {
        if (Bucket.UseSynchLock)
        {
            lock (lockInstance)
            {
                action();
            }
        }

        action();
    }
}

With the following, I can finally say goodbye to buggy HttpSessionState code in legacy systems and even support session isolation.

public class HttpSessionDataBucket : IDataBucket
{
    private readonly string bucketName;

    public HttpSessionDataBucket() : this(typeof (IDataBucket))
    {}

    public HttpSessionDataBucket(Type forType) : this(forType.FullName)
    {}

    public HttpSessionDataBucket(string bucketName)
    {
        this.bucketName = bucketName;
    }

    private Hashtable Bucket
    {
        get
        {
            HttpSessionState session = HttpContext.Current.Session;
            object ht = session[bucketName];

            if (ht is HashtableDataBucket)
                return (Hashtable) ht;

            session[bucketName] = ht = new Hashtable();

            return ht as Hashtable;
        }
    }

    public object this[object key]
    {
        get { return Bucket[key.ToString()]; }
        set { Bucket[key.ToString()] = value; }
    }

    public bool ContainsKey(object key)
    {
        return Bucket[key.ToString()] != null;
    }

...
}
ILocalData localData = new LocalData(new HttpSessionDataBucket(typeof(IMenuItem)));

This is obviously still evolving but, for now, I love being able to have an ILocalData instance in my domain objects (most likely not session buckets though) and being able to call “localData.Clear();” without messing up the rest of the system.

It’s amazing how far we’ll go sometimes. Schwew! ;)

-=Code Well