Logo

NHibernate

The object-relational mapper for .NET

NHibernate and virtual methods/properties

NOTE: This post was originally published on July 4, 2008

I love NHibernate but one of the things that bothers the hell out of me is that i keep forgetting to add the virtual keyword to each method or property in my entities. And since NHibernate needs your classes' properties and methods to be virtual, this causes run-time errors when i run my tests. Since i'm already using custom compile time checks, i figured i might as well add another one... from now on, i want my compilation to fail if any of my NHibernate entities have public methods/properties that aren't marked virtual. Once again, it's PostSharp to the rescue:

using System;

using System.Reflection;

 

using PostSharp.Extensibility;

using PostSharp.Laos;

 

namespace Northwind.Aspects

{

    [Serializable]

    [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Method | AttributeTargets.Property)]

    [MulticastAttributeUsage(MulticastTargets.Method, TargetMemberAttributes = MulticastAttributes.Managed |

        MulticastAttributes.NonAbstract | MulticastAttributes.Instance |

        MulticastAttributes.Protected | MulticastAttributes.Public)]

    public class RequireVirtualMethodsAndProperties : OnMethodBoundaryAspect

    {

        public override bool CompileTimeValidate(MethodBase method)

        {

            if (!method.IsVirtual)

            {

                string methodName = method.DeclaringType.FullName + "." + method.Name;

 

                var message = new Message(SeverityType.Fatal, "MustBeVirtual",

                    string.Format("{0} must be virtual", methodName), GetType().Name);

                MessageSource.MessageSink.Write(message);

 

                return false;

            }

 

            return true;

        }

    }

}

And then we make sure this check is applied to my NHibernate entities:

#if DEBUG

[assembly: RequireVirtualMethodsAndProperties(AttributeTargetTypes = "Northwind.Domain.Entities.*")]

#endif

Now, whenever i forget to mark my properties/methods as virtual, i get this:

EXEC : error MustBeVirtual: Northwind.Domain.Entities.Region.RemoveTerritory must be virtual

EXEC : error MustBeVirtual: Northwind.Domain.Entities.Region.AddTerritory must be virtual

EXEC : error MustBeVirtual: Northwind.Domain.Entities.Region.get_Territories must be virtual

EXEC : error MustBeVirtual: Northwind.Domain.Entities.Region.set_Description must be virtual

EXEC : error MustBeVirtual: Northwind.Domain.Entities.Region.get_Description must be virtual

EXEC : error MustBeVirtual: Northwind.Domain.Entities.Region.set_Id must be virtual

EXEC : error MustBeVirtual: Northwind.Domain.Entities.Region.get_Id must be virtual

 

... Done building project "Northwind.csproj" -- FAILED.

 

And there we go :)


Posted Sun, 31 August 2008 06:02:00 AM by DavyBrion
Filed under: postsharp, virtual, validation, proxy

comments powered by Disqus
© NHibernate Community 2024