Lucene.Net

April 30, 2007

Mike, one of the co-founders of Atlassian has posted some interesting slides on Lucene, a Java OSS reverse indexing project. The slides give some insight into how Jira and Confluence make use of Lucene’s capabilities.

About two years ago, I was driving to the Snowy Mountains with Atlassian’s other founder Scott, who was waxing lyrically about the virtues of Lucene and how it could help solve Campaign Masters then current performance problem.

Two years on, Atlassian is five years old and Lucene.Net has long since been the solution to one of our biggest teething issues. Again we are looking to Lucene to do for us what our database can not, on a clustered scale. Mike’s slides cover their scaling issues and what their options and problems were for clustering. Fortunately, our situation seems much less complex and we will be testing the speed of Lucene using indexes on network storage.

Lucene.Net, AFAIK, is up to 1.9 and doesn’t currently support the Update/Delete features of it’s 2.1 Java sister.


The Evil of ObjectDataSource Overcome….

April 12, 2007

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;
}
}