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?