Take the 2-minute tour ×

As of version 2.1, NHibernate supports constructor injection for IUserTypes via IoC container (supplied through the ByteCodeProvider config setting).

However, when I try to get this working through Fluent NHibernate configuration (not auto mapping), when I build my configuration, I get an exception complaining that one of my objects (a custom ICompositeUserType, in this case) does not have an empty default constructor.

I traced this exception down to a call to Activator.CreateInstance() in FluentNHibernate.Mapping.PropertyPart.AddColumnsFromCompositeUserType(Type compositeUserType).

The whole point of NHibernate's IoC support feature was to replace calls to Activator.CreateInstance with calls to the provided custom ByteCodeProvider.

So I guess my question is this: is it possible to get this working with Fluent NHibernate, or do I have to scrap my Fluent NH configuration and go back to NHibernate's built-in programmatic configuration?

Links to blog posts about this feature:

UPDATE: it looks like the problem is with FluentNHibernate's handling of custom implementations of ICompositeUserType. I changed my Composite User Types to IUserType (which is probably better suited for what the classes actually were), and it looks like Fluent NHibernate is cooperating now.

UPDATE #2: Adding an empty constructor does solve the problem - I'd mark this as answered, but the suggestion came in a comment instead of an answer, so I'm upvoting those comments (until an official answer is added).

share|improve this question
I don't know the answer, but I'm pretty sure that you can freely mix XBM and fluent mappings, so in any event you won't have to scrap your whole FNH effort. –  Jay Jan 7 '11 at 17:45
What happens if you provide a default empty constructor (public or protected)? –  Jamie Ide Jan 7 '11 at 18:20
@Jamie Ide, I just realized that your suggestion, as simple as it sounds, is exactly what Rich and I are discussing below. I'll give it a try and report back. –  James Nail Jan 7 '11 at 21:15
add comment

1 Answer

up vote 0 down vote accepted

Keep in mind that all Fluent NHibernate does is create the same configuration object structure that utilziing NHibernate XML would. How are you trying to set the ByteCodeProvider via Fluent NHibernate?

share|improve this answer
Well right now, I'm calling NhEnvironment.BytecodeProvider = new MyCustomBytecodeProvider(_container); right before fluentConfig.BuildConfiguration() (which is where the exception comes up). From what I see in the Fluent NH source, it's probably never gonna matter where I call it, because it still uses Activator.CreateObject() without any apparent conditional logic to instantiate my user types when it generates the mapping configs. –  James Nail Jan 7 '11 at 18:12
What confused me is why Fluent NHibernate would even care about instantiating the ICompositeUserType in the first place. By the way, in the GitHub code, I don't see a PropertyPart class, but I do see the method you mention in Builders.PropertyBuilder class. If i had to guess, it has to do conventions, so that the each of the appropriate properties in the composite type have columns mapped to them. Assuming this, it seems as if you'd be OK with adding a empty constructor, since it should only be invoked by Fluent code for gathering metadata. NHibernate itself would hopefully use the IOC. –  Rich Jan 7 '11 at 21:01
good point, but now I have to show my ignorance and ask, given two public constructors (one with args, and the other without), will an IoC container like StructureMap use the empty one instead? And if so, would Fluent's Activator.CreateInstance() call work on that class if I make the empty constructor protected? –  James Nail Jan 7 '11 at 21:11
A protected constructor would only be accessible from a subclass, so that won't work. Just for testing purposes, you could set a flag in the empty constructor and check it in the ICompositeUserType methods and throw exception if called from empty constructor to test StructureMaps instantiation. –  Rich Jan 7 '11 at 22:01
add comment

Your Answer


