The Evil of ObjectDataSource Overcome….

Well for me at least.
I had the need to use the ObjectDataSource but wanted to get the “Business Object” from our IoC container, rather than the default method of the Activator created instance. We needed a stateful object that could modify a list of data objects in volatile storage at our databound controls beck and call. This simple task wasn’t so simple.

<Rant>
The ASP.NET team clearly thinks that they are the be all and end all of software design as most remotely powerful classes are locked down with private or internal modifiers.
</Rant>

Some Googling found this guy who had felt the pain, enough I might add to raise more than a handful of issues with microsoft, all of which were promptly set to a status of “won’t fix”. Sound familiar? Marc solved the issue by creating his own datasource control and view and through heavy reflection has solved his problem.

I was not satisfied with the reflection road so I started develing into the documentation. Previous examples had all been using the “Parameters” method of making updates and deletes. That is they specify in the markup the names and types of the parameters on the Update and Delete methods. This had never impressed me much (I still wish there was an easy way of coding new Class().Method.Name  😉 ) and so when I came across the DataObjectTypeName I found a new path to follow.

Briefly the DataObjectTypeName allows you to specify the type of your actual object that you update, insert, delete etc. The ObjectDataSourceView then uses reflection to bind the Databound controls values to an instance of that dumb object. The dumb object is then passed into the Update, Delete methods of the object that is created from the TypeName property. This lead to the realisation that I only needed 4 methods for an instance of the DataSource control; Select, Update(object item), Insert(object item) and Delete(object item).

I can handle implementing the Proxy Pattern for four methods… so I did.
The ObjectDataSource control specifies the TypeName of the proxy class which using generics allows me to pass the Type of the class i want resolved from the IoC container.
The proxy then just passes of the calls to the real “BusinessObject”.
This solution makes use generics so the type names are too cumbersome to be added to markup (plus I don’t like type names in markup) so I create classes for each datasource I need.

public interface IDataObjectContainer<T>
{
int Delete(T item);
int Insert(T newItem);
IList<T> Select();
int Update(T newItem);
}

public class DataObjectProxy<TContainer, T> where TContainer : IDataObjectContainer<T>
{
private TContainer proxiedObject;

public DataObjectProxy()
{
proxiedObject = ResolveInstance();
}

protected virtual TContainer ResolveInstance()
{
return (TContainer)Activator.CreateInstance(typeof(TContainer));
//return IoC.Resolve<TContainer>();
}

[DataObjectMethod(DataObjectMethodType.Select)]
public IList<T> Select()
{
return proxiedObject.Select();
}

[DataObjectMethod(DataObjectMethodType.Insert)]
public int Insert(T newItem)
{
return proxiedObject.Insert(newItem);
}

[DataObjectMethod(DataObjectMethodType.Update)]
public int Update(T changedItem)
{
return proxiedObject.Update(changedItem);
}

[DataObjectMethod(DataObjectMethodType.Delete)]
public int Delete(T item)
{
return proxiedObject.Delete(item);
}
}

An example of my strongly typed ObjectDataSource is as follows, note the DataObjectSessionContainer and Item classes are missing. They are just proof of concepts, Item is my dumb data object for the example and DataObjectSessionContainer is the implementation that modifies the a list of items in the session.


public class ItemSessionObjectDatasource : ObjectDataSource
{
public ItemSessionObjectDatasource()
{
this.TypeName = typeof (DataObjectProxy<DataObjectSessionContainer<Item>, Item>).FullName;
this.DataObjectTypeName = typeof (Item).FullName;
}
}

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: