Adding Support for ISupportInitialize in NHibernate

The .NET ISupportInitialize interface is used when we want to support staged initialization for objects. Its BeginInit method is called when initialization is about to start and EndInit when it is finished.

If we want, it is easy to add support for it in NHibernate. An option would be:

  • BeginInit is called when the object is instantiated, like when NHibernate has loaded a record from the database and is about to hydrate the entity, and immediately after the Id property is set;
  • EndInit is called after all properties are set.

We do this by using a custom interceptor, like we have in the past. We start by writing a class that inherits from EmptyInterceptor, and implements the listener interface for the PostLoad event, IPostLoadEventListener:

   1: public sealed class SupportInitializeInterceptor : EmptyInterceptor, IPostLoadEventListener

   2: {

   3:     private ISession session = null;

   4:  

   5:     public override void SetSession(ISession session)

   6:     {

   7:         this.session = session;

   8:         base.SetSession(session);

   9:     }

  10:  

  11:     public override Object Instantiate(String clazz, EntityMode entityMode, Object id)

  12:     {

  13:         var listeners = (this.session.SessionFactory as SessionFactoryImpl).EventListeners;

  14:         var metadata = this.session.SessionFactory.GetClassMetadata(clazz);

  15:         var proxy = metadata.Instantiate(id, entityMode);

  16:         var initializable = proxy as ISupportInitialize;

  17:  

  18:         if (initializable != null)

  19:         {

  20:             initializable.BeginInit();

  21:         }

  22:  

  23:         if (listeners.PostLoadEventListeners.OfType<SupportInitializeInterceptor>().Any() == false)

  24:         {

  25:             listeners.PostLoadEventListeners = listeners.PostLoadEventListeners.Concat(new IPostLoadEventListener[] { this }).ToArray();

  26:         }

  27:  

  28:         return (proxy);

  29:     }

  30:  

  31:     #region IPostLoadEventListener Members

  32:  

  33:     void IPostLoadEventListener.OnPostLoad(PostLoadEvent @event)

  34:     {

  35:         var initializable = @event.Entity as ISupportInitialize;

  36:  

  37:         if (initializable != null)

  38:         {

  39:             initializable.EndInit();

  40:         }

  41:     }

  42:  

  43:     #endregion

  44: }

Then, before creating a session factory, we need to register it in the Configuration instance:

   1: var sessionFactory = cfg.SetInterceptor(new SupportInitializeInterceptor()).BuildSessionFactory();

Now, if your entity implements ISupportInitialize, NHibernate will automagically call its methods at the proper time. As simple as this! Winking smile

Lesser-Known NHibernate Features – Generating Database Scripts

As you may know, NHibernate knows how to generate the database for you from its model. Any of the supported databases will do.

What you may not know is that you can simply generate the SQL scripts that would be used to either generate the database from scratch or just update it to match the model as it is. For that you use the SchemaExport and SchemaValidator classes.

SchemaValidator takes a Configuration instance and basically throws an exception if, when its Validate method is called, the database does not match the model.

SchemaExport has far more options; it can:

  • Create or drop a database model based on the entity model;
  • Output the SQL to a file, either executing it at the same time or not;
  • Execute the SQL to another arbitrary database connection;
  • Execute a custom action after each line of the generated SQL script.

An example:

   1: var validator = new SchemaValidator(cfg);

   2:  

   3: try

   4: {

   5:     validator.Validate();

   6: }

   7: catch

   8: {

   9:     var export = new SchemaExport(cfg).SetOutputFile("Script.sql");

  10:  

  11:     //send the script to standard output and execute it

  12:     export.Execute(useStdOut: true, execute: true, justDrop: false);

  13:     //or

  14:     //send all lines of the script to the System.Console.WriteLine method

  15:     export.Execute(scriptAction: System.Console.WriteLine, execute: false, justDrop: false);

  16: }

Unity, Part 9: Integration With Managed Extensibility Framework

This time, I will be talking about integrating Unity with Managed Extensibility Framework (MEF). You can find the other posts in the series here (how to use Unity in a web application), here (adding Interfaces), here (registration by convention), here (injecting values), here (extensions), here (aspect-oriented programming), here (dependency injection) and the first one here (introduction).

The Managed Extensibility Framework (MEF) has been around since the release of .NET 4.0, and even before as a beta, stand-alone package. Basically, it provides an extensible mechanism for detecting and loading plugins. It’s easier to use than the similarly-named Managed Add-In Framework (MAF), and even if it’s not so feature-rich (it doesn’t support sandboxing, for once), unlike MAF, it is well alive!

So, what does MEF offer that can be of use to Unity? Well, MEF knows how to locate exports/plugins from a number of locations, like assemblies and file system directories. It’s just a matter of finding the exports we’re interested in and registering them with Unity.

An export in MEF is some class that is decorated with an ExportAttribute (technically speaking, this is just when using the Attributed Programming Model, since .NET 4.5 there is also the Convention-Based Programming Model). This attribute allows specifying the type to export (ContractType) and also the contract name (ContractName). This matches closely the Unity/IoC concept of contract type and name.

We could find all exports under a given path using MEF using an AssemblyCatalog, a particular implementation of a ComposablePartCatalog:

   1: var catalog = new AssemblyCatalog("some path");

A couple of helper functions for picking up the export’s contract type and name, by leveraging the ReflectionModelServices class:

   1: public static IDictionary<String, Type> GetExportedTypes<T>(this ComposablePartCatalog catalog)

   2: {

   3:     return (GetExportedTypes(catalog, typeof(T)));

   4: }

   5:  

   6: public static IDictionary<String, Type> GetExportedTypes(this ComposablePartCatalog catalog, Type type)

   7: {

   8:     return (catalog.Parts.Where(part => IsComposablePart(part, type) == true).ToDictionary(part => part.ExportDefinitions.First().ContractName, part => ReflectionModelServices.GetPartType(part).Value));

   9: }

  10:  

  11:  

  12: private static Boolean IsComposablePart(ComposablePartDefinition part, Type type)

  13: {

  14:     return (part.ExportDefinitions.Any(def => (def.Metadata.ContainsKey("ExportTypeIdentity") == true) && (def.Metadata["ExportTypeIdentity"].Equals(type.FullName) == true)));

  15: }

This will return a collection of key-value pairs, where the key is the contract name and the value the contract type; this is so there can be multiple contract names for a given contract type. After we have this, it’s just a matter of iterating the results and registering each occurrence:

   1: var type = typeof(ISomeType);

   2: var exports = catalog.GetExportedTypes(type);

   3:  

   4: foreach (var entry in exports)

   5: {

   6:     unity.RegisterType(type, entry.Value, entry.Key);

   7: }

So, given the following contract and implementations:

   1: public interface ISomeType

   2: {

   3:     void SomeMethod();

   4: }

   5:  

   6: [Export("Some", typeof(ISomeType))]

   7: public class SomeImplementation : ISomeType

   8: {

   9:     public void SomeMethod() { }

  10: }

  11:  

  12: [Export("Another", typeof(ISomeType))]

  13: public class AnotherImplementation : ISomeType

  14: {

  15:     public void SomeMethod() { }

  16: }

We can obtain a specific contract type implementation given it’s name:

   1: var myImplementation = unity.Resolve<ISomeType>("MyName");

And also all implementations of the contract that were found:

   1: var all = unity.ResolveAll<ISomeType>();

This can be enhanced in a couple of ways:

  • Use a Unity extension to automatically find and register exports at runtime;
  • Make use of MEF metadata to tell Unity which lifetime managers to use, and other useful properties, such as the default implementation for the contract type.

As usual, I’m looking forward for your comments!

ASP.NET Web Forms Prompt Validator

For those still using Web Forms and Microsoft’s validation framework, like yours truly – and I know you’re out there! -, it is very easy to implement custom validation by leveraging the CustomValidator control. It allows us to specify both a client-side validation JavaScript function and a server-side validation event handler.

In the past, I had to ask for confirmation before a form was actually submitted; the native way to ask for confirmation is through the browser’s confirm function, which basically displays a user-supplied message and two buttons, OK and Cancel. I wrapped it in a custom reusable validation control, which I am providing here:

   1: [DefaultProperty("PromptMessage")]

   2: public sealed class PromptValidator : CustomValidator

   3: {

   4:     [DefaultValue("")]

   5:     public String PromptMessage { get; set; }

   6:  

   7:     protected override void OnPreRender(EventArgs e)

   8:     {

   9:         var message = String.Concat("\"", this.PromptMessage, "\"");

  10:  

  11:         if ((this.PromptMessage.Contains("{0}") == true) && (this.ControlToValidate != String.Empty))

  12:         {

  13:             message = String.Concat("String.format(\"", this.PromptMessage, "\", args.Value)");

  14:         }

  15:  

  16:         this.ClientValidationFunction = String.Concat("new Function('sender', 'args', 'args.IsValid = confirm(", message, ")')");

  17:         this.EnableClientScript = true;

  18:  

  19:         base.OnPreRender(e);

  20:     }

  21: }

A sample usage without any target control might be:

   1: <web:PromptValidator runat="server" PromptMessage="Do you want to submit your data?" ErrorMessage="!"/>

And if you want to specifically validate a control’s value:

   1: <web:PromptValidator runat="server" PromptMessage="Do you want to accept {0}?" ErrorMessage="!" ControlToValidate="text" ValidateEmptyText="true"/>

When submitting your form, you will get a confirmation prompt similar to this (Chrome):

image

NHibernate Pitfalls: Versioned Entities Are Not Batcheable

This is part of a series of posts about NHibernate Pitfalls. See the entire collection here.

This is a problem similar to the one with native id generators. Basically, because there are different versioning strategies – timestamp, counter, native, etc, – NHibernate needs to issue a SELECT after a versioned entity is INSERTEd or UPDATEd. While this wouldn’t be necessary when NHibernate manages the version on the “client side”, like:

   1: UPDATE MyEntity SET Version = 2 WHERE ...;

   2: //or

   3: UPDATE MyEntity SET Version = GETDATE() WHERE ...;

But not if the version is handled on the database side, like when using SQL Server’s ROWVERSION/TIMESTAMP columns or Oracle’s ORA_ROWSCN pseudo-columns. In these cases, NHibernate needs to issue a SELECT after each INSERT or UPDATE:

   1: UPDATE MyEntity SET ... WHERE ...;

   2: SELECT Version FROM MyEntity WHERE ...;

This breaks batching, because it needs to be done immediately after each INSERT/UPDATE.

Generating GDI+ Images for the Web

.NET’s Graphics Device Interface (GDI+) is Microsoft’s .NET wrapper around the native Win32 graphics API. It is used in Windows desktop applications to generate and manipulate images and graphical contexts, like those of Windows controls. It works through a set of operations like DrawString, DrawRectangle, etc, exposed by a Graphics instance, representing a graphical context and it is well known by advanced component developers. Alas, it is rarely used in web applications, because these mainly consist of HTML, but it is possible to use them. Let’s see how.

Let’s start by implementing a custom server-side control inheriting from Image:

   1: public class ServerImage: Image

   2: {

   3:     private System.Drawing.Image image;

   4:

   5:     public ServerImage()

   6:     {

   7:         this.ImageFormat = ImageFormat.Png;

   8:         this.CompositingQuality = CompositingQuality.HighQuality;

   9:         this.InterpolationMode = InterpolationMode.HighQualityBicubic;

  10:         this.Quality = 100L;

  11:         this.SmoothingMode = SmoothingMode.HighQuality;

  12:     }

  13:

  14:     public Graphics Graphics { get; private set; }

  15:

  16:     [DefaultValue(typeof(ImageFormat), "Png")]

  17:     public ImageFormat ImageFormat { get; set; }

  18:

  19:     [DefaultValue(100L)]

  20:     public Int64 Quality { get; set; }

  21:

  22:     [DefaultValue(CompositingQuality.HighQuality)]

  23:     public CompositingQuality CompositingQuality { get; set; }

  24:

  25:     [DefaultValue(InterpolationMode.HighQualityBicubic)]

  26:     public InterpolationMode InterpolationMode { get; set; }

  27:

  28:     [DefaultValue(SmoothingMode.HighQuality)]

  29:     public SmoothingMode SmoothingMode { get; set; }

  30:

  31:     protected override void OnInit(EventArgs e)

  32:     {

  33:         if ((this.Width == Unit.Empty) || (this.Height == Unit.Empty) || (this.Width.Value == 0) || (this.Height.Value == 0))

  34:         {

  35:             throw (new InvalidOperationException("Width or height are invalid."));

  36:         }

  37:

  38:         this.image = new Bitmap((Int32)this.Width.Value, (Int32)this.Height.Value);

  39:         this.Graphics = System.Drawing.Graphics.FromImage(this.image);

  40:         this.Graphics.CompositingQuality = this.CompositingQuality;

  41:         this.Graphics.InterpolationMode = this.InterpolationMode;

  42:         this.Graphics.SmoothingMode = this.SmoothingMode;

  43:

  44:         base.OnInit(e);

  45:     }

  46:

  47:     protected override void Render(HtmlTextWriter writer)

  48:     {

  49:         var builder = new StringBuilder();

  50:

  51:         using (var stream = new MemoryStream())

  52:         {

  53:             var codec = ImageCodecInfo.GetImageEncoders().Single(x => x.FormatID == this.ImageFormat.Guid);

  54:

  55:             var parameters = new EncoderParameters(1);

  56:             parameters.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, this.Quality);

  57:

  58:             this.image.Save(stream, codec, parameters);

  59:

  60:             builder.AppendFormat("data:image/{0};base64,{1}", this.ImageFormat.ToString().ToLower(), Convert.ToBase64String(stream.ToArray()));

  61:         }

  62:

  63:         this.ImageUrl = builder.ToString();

  64:

  65:         base.Render(writer);

  66:     }

  67:

  68:     public override void Dispose()

  69:     {

  70:         this.Graphics.Dispose();

  71:         this.Graphics = null;

  72:

  73:         this.image.Dispose();

  74:         this.image = null;

  75:

  76:         base.Dispose();

  77:     }

  78: }

Basically, this control discards the ImageUrl property and replaces it with a Data URI value generated from a stored context. You need to define the image’s Width and Height and you can also optionally specify other settings such as the image’s quality percentage (Quality), compositing quality (CompositingQuality), interpolation (InterpolationMode) and smoothing modes (SmootingMode). These settings can be used to improve the outputted image quality.

Finally, you use it like this. First, declare a ServerImage control on your page:

   1: <web:ServerImage runat="server" ID="image" Width="200px" Height="100px"/>

And then draw on its Context like you would in a Windows application:

   1: protected override void OnLoad(EventArgs e)

   2: {

   3:     this.image.Graphics.DrawString("Hello, World!", new Font("Verdana", 20, FontStyle.Regular, GraphicsUnit.Pixel), new SolidBrush(Color.Blue), 0, 0);

   4:

   5:     base.OnLoad(e);

   6: }

Basically, this control discards the ImageUrl property and replaces it with a Data URI value generated from a stored context. You need to define the image’s Width and Height and you can also optionally specify other settings such as the image’s quality percentage (Quality), compositing quality (CompositingQuality), interpolation (InterpolationMode) and smoothing modes (SmootingMode). These settings can be used to improve the outputted image quality.

Finally, you use it like this. First, declare a ServerImage control on your page:

   1: <web:ServerImage runat="server" ID="image" Width="200px" Height="100px"/>

And then draw on its Context like you would in a Windows application:

   1: protected override void OnLoad(EventArgs e)

   2: {

   3:     this.image.Graphics.DrawString("Hello, World!", new Font("Verdana", 20, FontStyle.Regular, GraphicsUnit.Pixel), new SolidBrush(Color.Blue), 0, 0);

   4:

   5:     base.OnLoad(e);

   6: }

The result is this IMG tag with a Data URI content, that you can save or copy to the clipboard:

image

Pretty sleek, don’t you think? Winking smile

Conditional Content in SharePoint Markup

In SharePoint, there are several web parts that allow us to have different contents depending on some conditions:

  • LoginView (ASP.NET): allows the definition of templates per authenticated or anonymous user:
<asp:LoginView runat="server">

    <AnonymousTemplate>

        <!-- anonymous content -->

    </AnonymousTemplate>

    <LoggedInTemplate>

        <!-- authenticated content -->

    </LoggedInTemplate>

    <RoleGroups>

        <asp:RoleGroup Roles="Admin">

            <ContentTemplate>

                <!-- admin content -->

            </ContentTemplate>

        </asp:RoleGroup>

    </RoleGroups>

</asp:LoginView>

<SharePoint:SPSecurityTrimmedControl runat="server" PermissionMode="All" PermissionContext="CurrentSite" Permissions="ManageWeb">

    <!-- secure content -->

</SharePoint:SPSecurityTrimmedControl>

  • EditModePanel: for displaying contents in a web part page depending on its edit mode:
<PublishingWebControls:EditModePanel runat="server" PageDisplayMode="Edit">

    <!-- edit content -->

</PublishingWebControls:EditModePanel>

<SharePoint:UIVersionedContent runat="server" UIVersion="4">

    <ContentTemplate>

        <!-- content for SharePoint 2010 -->

        <!-- no code is run if does not match UIVersion -->

    </ContentTemplate>

</SharePoint:UIVersionedContent>

 

 

<SharePoint:VersionedPlaceholder runat="server" UIVersion="4">

    <!-- content for SharePoint 2010 -->

    <!-- code is always run but not rendered if does not match UIVersion -->

</SharePoint:VersionedPlaceholder>

  • AuthoringContainer: displays content depending on whether the current user has write or read rights on the current page or if it has an associated list item:
<PublishingWebControls:AuthoringContainer runat="server" DisplayAudience="ReadersOnly">

    <!-- content for readers -->

</PublishingWebControls:AuthoringContainer>

<PublishingWebControls:DeviceChannelPanel runat="server" IncludedChannels="iPhone">

    <!-- content for iPhones -->

</PublishingWebControls:DeviceChannelPanel>

  • DataViewWebPart: allows the passing of parameters and the usage of XSL for rendering logic;

I imagine you are now rolling your eyes: DataViewWebPart? how come? Well, because it doesn’t need to point to a specific list or view (unlike XsltListViewWebPart), it is very useful for markup-based customizations that will only depend on parameters:

   1: <WebPartPages:DataFormWebPart runat="server" Title="Conditional Content">

   2:     <ParameterBindings>

   3:         <ParameterBinding Name="MyParameter" Location="QueryString(MyParameter)"/>

   4:     </ParameterBindings>

   5:     <XSL>

   6:         <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl asp" xmlns:asp="System.Web.UI.WebControls">                                                  

   7:             <xsl:param name="MyParameter"/>                                                                                                                                        

   8:             <xsl:template match="/">

   9:                 <asp:Label runat="server" Text="Some content, just to show ASP.NET controls inside a SharePoint DataFormWebPart"/>

  10:                 <xsl:choose>

  11:                     <xsl:when test="$MyParameter=''">

  12:                         No parameter...

  13:                     </xsl:when>

  14:                     <xsl:otherwise>

  15:                         Allright! <xsl:value-of select="$MyParameter"/>

  16:                     </xsl:otherwise>

  17:                 </xsl:choose>                                                                                                

  18:             </xsl:template>

  19:         </xsl:stylesheet>

  20:     </XSL>                                        

  21: </WebPartPages:DataFormWebPart>

You can use this technique for:

  • Including scripts and stylesheets;
  • Including server-side controls.

It’s just a matter of rolling out some XSL to the rescue!

You may be already familiar with the available parameters, but you can find the full list here: http://msdn.microsoft.com/en-us/library/office/ff630170(v=office.15).aspx.

Another SharePoint Designer-only solution that may come in handy! 😉