In the Lab: Amplify.ActiveRecord (porting ruby to c#)
I’ve been secretly working on an active record type of port as a part of the Amplify Framework. The release of the ASP.Net MVC framework along with an MVC/MVP/Rails has really pushed me in that direction. So far there is both Subsonic and Castle’s MonoRail which ports a significant amount of code into .Net. However a lot of Rails like paradigms are somewhat lost as everything seems to be extremely object oriented versus using strings or even api calls. (Though MonoRail does have a very cool Inflector class which is a port of methods like pluralize & humanize, etc.
So basically I’m prototyping using Linq as the base for making queries at this point, and plan to then use the same API to do an adapter that uses ADO.Net, and hopefully this will go hand in hand with the new ASP.Net MVC framework. If you want to play with the alpha stage bits (with no warranties of code compiling at any given time as this is a prototype) then feel free to download from the projects new home.
svn checkout http://amplify-net.googlecode.com/svn/trunk/ amplify-net-read-only
Below is code from what you might find in subsonic, which does have a very cool query object, but still takes more of a .Net approach, when using the API.
ProductCollection products = new ProductCollection().Where("categoryID", 1).OrderByAsc("listOrder").Load();
ProductCollection products = new ProductCollection().Load(new Query("Products").ExecuteReader());
So my goal is to do more of a direct port that has methods like .New(), .Create(), .Find() and using convention over things like heavy strongly typed objects. I’m probably going to make use of .Net 3.5 since the ASP.Net MVC is using 3.5. I’m also going to make these objects decorated so that you can do something like the following verses using reflection or having to set/get every property.
Products list = Product.Find(new Selection().Where("Name Like '%?'", "A").SortBy("listOrder ASC"));//ado.net sql
Product product = Product.Find(12);
Product product = Product.Find("Name = '?' AND Age = ?", "michael", 28));
Product product = Product.Find("by_Name_and_Age", "michael", 28));
var x = Product.Find(new Options().Where("Name.StartsWith(@0) || Name.StartsWith(@1)", "a", "b").SortBy("Name DESC")); //using System.Linq.Dymanic
// in the page_load
ds.Inserted += new ObjectDataSourceStatusEventHandler(ds_Inserted);
ds.Updated += new ObjectDataSourceStatusEventHandler(ds_Updated);
void ds_Inserted(object sender, ObjectDataSourceStatusEventArgs e) {
list.Add(Person.Create(e.OutputParameters));
}
void ds_Updated(object sender, ObjectDataSourceStatusEventArgs e) {
Person person = GetPerson();
person.Merge(e.OutputParameters); //IDictionary
person.Save();
person["Name"] = "Michael"; // or
person.Age = 28;
person.Save();
person.Merge(new Hashtable() {
{"Name", "Bob"},
{"Age", 10}
});
person.Save();
}
// or in the new MVC framework
// click here to see what MVC looks like with linq
[ControllerAction]
public void Create() {
Person.Create(Request.Form); //IDictionary
RedirectToAction(new { Action = “Category”, ID = production.CategoryID});
}
So you can see above that the objects have both strongly type properties and a dictionary style accessors as well so you could easily map objects using a foreach statement (which the .Merge will do) versus having to use reflection, which is also true when pulling data from a datareader.
Other goal will be to make the objects utilize Linq and replace the code that SQLMetal currently generates, so designing Linq compatibility and working on a code generator is also in the works. Since I’m using .Net 3.5, I can abuse static methods in order to make writing CodeDom a lil easier.
December 11th, 2007 at 10:58 am
I’ve been a LI user for only a few months and have wondered how to make it useful. This is hopeful news. Thanks for reporting it.
David
December 12th, 2007 at 7:50 pm
I admit that 99% of the time, I just accept invitations to LinkIn, and I am not an active Linker. Maybe now people will come up with more useful presentations of the information in LinkedIn. My fingers are crossed. You cannot overestimate the power of having an open system which others can plug into.