Showing changes from revision #1 to #2: Added | Removed
Conventions are small self-contained chunks of behavior that get applied to the mappings Fluent NHibernate generates. These conventions are of varying degrees of granularity, and can be as simple or complex as you require. Fluent NHibernate has a default set of conventions that it uses to generate your mappings, if these choices don't match your design then you can implement your own.
The conventions are built using a set of interfaces that each defines two methods, Accept
and Apply
, with varying parameters based on the kind of convention you're creating. The Accept
method is called in the mapping generation cycle to see if the specific convention implementation wants to be applied to that mapping; returning true in this method will result in your convention being applied to that mapping. Apply
is called if your convention is accepted, this is where you actually make the changes to the mappings.
Lets start by implementing a class convention, which gets applied to any ClassMap<T>
mappings.
public class LowercaseTableNameConvention : IClassConvention { public bool Accept(IClassMap classMap) { // acceptance criteria } public void Apply(IClassMap classMap) { // alterations } }
This is an empty class convention, you can see the two methods I mentioned. For this example I'm going to make this convention be applied to all class mappings, but you can analyse the IClassMap
instance to your hearts extent to determine whether the convention should be applied.
public bool Accept(IClassMap classMap) { return true; // apply to everything }
Then we need to implement the Apply
behavior, again you can use the IClassMap
instance but this time you alter it with your conventional changes.
public void Apply(IClassMap classMap) { classMap.WithTable(classMap.EntityType.Name.ToLower()); }
That's Apply
implemented, all we're doing is setting the table name to always be lowercase. Simple.
Here's the whole convention:
public class LowercaseTableNameConvention : IClassConvention { public bool Accept(IClassMap classMap) { return true; // apply to everything } public void Apply(IClassMap classMap) { classMap.WithTable(classMap.EntityType.Name.ToLower()); } }
Now that we've created our convention, we need to inform Fluent NHibernate of how to use it. The simplest way to do this is just to use the Fluent Configuration mapping setup to use all conventions in an assembly, alternatively you can just add individual conventions. Both these are done through the ConventionDiscovery
property of the fluent mappings setup.
Fluently.Configure() .Database(/* database config */) .Mappings(m => { m.FluentMappings .AddFromAssemblyOf<Entity>() .ConventionDiscovery.AddFromAssemblyOf<LowercaseTableNameConvention>(); })
Alternatively you can use just Add
to add an instance or a type, or you can use the Setup
method to call a lambda that can be used to supply multiple different conventions (e.g. some from an assembly, and some individually).
Once you've set that up, Fluent NHibernate will automatically call your convention when it's generating the mappings.
A convention is required to have either a parameterless constructor (default or not), or a constructor taking a single instance of IConventionFinder
; if neither of those constructors exists then the convention will be either ignored (if added through AddFromAssemblyOf<T>
) or an exception thrown (if added explicitly). You can read more about the IConventionFinder
in Conventions Code.
If you were using our previous conventions API, then you may be interested in Converting To New Style Conventions, which explains the various differences you may encounter; however, there's nothing difficult about it, you just need to pick the right interface. If you're not quite comfortable with this change yet, the Conventions Shortcuts might be of some use.