tags:

views:

39

answers:

0

I have a plug-in infrastructure for a project I am working on. The requirement is that I have a base class, that 3rd parties can implement. I should be able to persist these 3rd party widgets to a single table.

The idea is that I have a table in our database that looks like the following:

(I couldn't upload an image of the table because my account is too new. Instead here's the table's definition)

CREATE TABLE [dbo].[WIDGET](
[WIDGET_ID] [int] IDENTITY(1,1) NOT NULL,
[WIDGET_NAME] [nvarchar](25) NOT NULL,
[OBJECT_TYPE] [nvarchar](200) NOT NULL,
[OBJECT_DATA] [nvarchar](max) NOT NULL,
    CONSTRAINT [PK_WIDGET] PRIMARY KEY CLUSTERED([WIDGET_ID] ASC)
)

The code for this base class would be:

public abstract class Widget
{
  public int Id { get; private set; }
  public string Name { get; set; }

  protected Widget() { }
  protected Widget(int id)
  {
    Id = id;
  }

  public abstract void Render(TextWriter output);
}

The 3rd party widgets would derive from this class can be registered with the application.

I need to be able to have NHibernate materialize a concrete instance of the stored abstract widget by inspecting the OBJECT_TYPE field and deserializing the value in the OBJECT_DATA field.

Some pseudo code for how I would achieve this out side of NHibernate would look like:

public Widget DeserializeWidget(Type type, string objectData)
{
  //argument Type type == The type contained in the OBJECT_TYPE column
  //argument string objectData == The serialized data from the OBJECT_DATA column

  DataContractJsonSerializer dcjs = new DataContractJsonSerializer(type);
  Widget result = null;

  byte[] buffer = Encoding.UTF8.GetBytes(objectData);

  using (MemoryStream ms = new MemoryStream(buffer))
  {
    result = (Widget)dcjs.ReadObject(ms);
  }
  return result;
}

How can I inject the above code (and the inverse SerializeWidget) into my NHibernate mappings when an HBL query returns a Widget entity?

Or is there a better way to do this with NHibernate, being that I have no idea of the shape of the concrete widgets that my application needs to persist?