Click to See Complete Forum and Search --> : Dynamically creating proxy classes in C#


Snap
April 21st, 2004, 12:39 AM
Hello all,

I'm writing a transparent persistent engine in C#. I'm now to the stage of storing collections, and am trying to figure out the 'right way' to do it.

Imagine the following class:

public class Foo {
private String aString;
private IList barList;
...
}

public class Bar {
private int anInt;
public int TheInt {get{...} set{...}}
}


In my first attempt, I have created a proxy for the list that implements lazy-loading. So, if the user never touches the barList, and saves Foo, there is no overhead and all is good.

However, if the user has accessed the barList, all elements are deleted and then re-inserted to the DB when Foo is saved. As you can imagine, this is quite inefficient in cases where the elements of barList are not altered (eg, only read and possibly displayed somewhere).

Now, the problem is how can the engine know that a Bar object has been updated. I have thought of three approaches:

The easiest way would be to have all persistent objects implement an interface with an isDirty() method. While easy to implement, I don't like the idea of forcing the client to add that to every object and accessor.

The next method I thought of would be to dynamically create a subclass of the object that could 'figure out' if it has been modified.

To accomplish this, I had the idea of sending back to the client a subclass of the original object that contains a snapshot of the restored object. When it comes time to update the object, the existing object would be compared against the snapshot clone, and if they differed, then the item would be saved. So, a snapshot object for Bar might look like:


public class BarSnapshot : Bar {
private Bar snapshot = new Bar();
public BarSnapshot(Bar b) {
snapshot.TheInt = b.TheInt;
this.TheInt = b.TheInt;
}

public bool isDirty() {
return this.TheInt.Equals(snapshot.TheInt);
}
}


Putting aside the implementation difficulties of dynamically generating the BarSnapshot class (I'm assuming for the moment that this is all possible using Reflection.Emit), my question is: is the cure worse than the cause?

Effectively, this approach would double the memory usage of the system, as each object would have the working copy and the original snapshot. However, updates and deletes would presumably be much quicker, as redundant updates/deletes would no longer occur.

This is about the best conceptual model for improving the efficiency of the system in a transparent mannor. I'm wondering if anyone out there might have any other approaches that would not incur so much overhead.

Regards,
Snap