In the previous post you saw a simple example about a way to use the new mapping-by-code of NHibernate 3.2.0.
The class-by-class mapping will be, probably, the most used way just because it is very similar to the XML mapping and the “feeling of loss of control” is near to zero (the quiet of sense).
If you want experiment more adrenaline you can try ConfORM but if you like just a little bit of more adrenaline you can use the NHibernate’s ConventionModelMapper.
Inside the ConventionModelMapperTo understand what really is the ConventionModelMapper let me show you a piece of its code:
clear! no? The ConventionModelMapper is just a specialization of a ModelMapper where, instead the ExplicitlyDeclaredModel, we are injecting another implementation of IModelInspector. To “simplify” its usage, and obscure to you the real power of Dependency-Injection, the ConventionModelMapper exposes some methods as, for instance:
What are those three parameters of the delegate ?
The name of the method is the question : is it a persistent property ?
The MemberInfo is the subject of the question. The bool parameter is an “help” to take a decision and it represent what was explicitly defined (we will see later where was defined). The last bool is the answer of the question.
What happen if we have a look to the implementation of the above method ?
As you can see the implementation is completely passed to the SimpleModelInspector, nothing more than an “simplification” to allow you the usage of just one class.
ConventionModelMapper vs class-by-class mappingThis is not a matter. All these ways to perform the mapping-task, in NHibernate 3.2.0, are not one versus others because you can use all together. You can organize your mapping as you feel more confortable. There will be users who prefer explicit-class-by-class for the whole mapping; there will be users who prefer the usage of ConventionModelMapper and the method-based-mapping to specify convention-exceptions/overrides; there will be users who prefer the usage of ConventionModelMapper and the class-by-class as an organization of convention-exceptions/overrides; there will be users who implements their IModelInspector based on attributes; there will be users who implements their IModelInspector based on a custom DSL.
The new mappingTaking the domain of the previous post, and some conventions already defined there, we can start from something like this:
More then the starting point (line 1), where I’m using just the constructor of ConventionModelMapper, the difference, so far, is from line 31 to 36. Because I have completely removed any kind of explicit mapping (that “incomplete class-by-class mapping”) I have to inform the ConventionModelMapper about:
- given a System.Type how recognize if it is an entity or not (line 32,33,34)
- given a System.Type how recognize if it is a root-entity (the top class of a hierarchy); line 31,35
- which are the classes that the ConventionModelMapper have to map (line 32, 36)
The mapping process is not completed because in the removed class-by-class mapping there was two specifications outside our required conventions: the Customer.TaxId as natural-id and the Order.EmissionDay as Date. To specify only these two convention-exceptions I can use the method-based-mapping in this way:
You can put the two lines in any place before call mapper.CompileMappingFor(entities).
The resultThe integration is pretty the same:
The difference is just at line 10.
After build the session-factory we will have again
And the XML will be (please look it closer):
The mapping is correct and it works but just for a “casualty”…