Entity that represents a persistable entity could look like this:
public class PersistableDelegate { public virtual Delegate Delegate { get; set; } public virtual string Name { get; set; } public virtual int Id { get; set; } private byte[] SerializedDelegate { get { if (Delegate == null) return null; var formatter = new BinaryFormatter(); using (var stream = new MemoryStream()) { formatter.Serialize(stream, this.Delegate); return stream.ToArray(); } set { if (value != null) { var formatter = new BinaryFormatter(); using (var stream = new MemoryStream(value)) Delegate = (Delegate)formatter.Deserialize(stream); } else Delegate = null; } } }
Your model can manipulate with Delegate property. SerializedDelegate property provides access to serialized data of the delegate for NHibernate – it is implementation detail and is marked as private. Getter of this property returns the delegate serialized to an array and the setter reconstructs the delegate from provided data.
FNH mapping is simple as breath then:
public class PersistableDelegateMap : ClassMap<PersistableDelegate> { public PersistableDelegateMap() { Id(x => x.Id); Map(x => x.Name); Map(Reveal.Member<PersistableDelegate>("SerializedDelegate")) .Length(int.MaxValue); } }Reveal class makes it possible to map private property.
Corresponding database table for MS SQL is:
CREATE TABLE [dbo].[PersistenceAction]( [Id] [int] IDENTITY(1,1) NOT NULL, [Name] [nvarchar](255) NULL, [SerializedDelegate] [image] NULL, )
Now it is possible to store a delegate in database:
var action = new PersistableDelegate(); action.Delegate = (Action)(() => { Console.WriteLine("Hello from persisted delegate!"); }); action.Name = "First test"; session.Save(action); session.Flush();
and load back:
var action = session.Query<PersistableDelegate>().Where(x => x.Name == "First test").FirstOrDefault(); action.Delegate.DynamicInvoke();
I am not sure yet how can be this useful. There are definitely many limitations, e.g. lambda expression closed over local variable is not serializable. In any case such feature is very promising...
No comments:
Post a Comment