3

I have a convention UserTypeConvention<MyUserType> where MyUserType : IUserType where MyUserType handles an enum type MyEnum. I have configured Fluent NHibernate thusly

sessionFactory = Fluently
                .Configure()
                .Database(MsSqlConfiguration.MsSql2005.ConnectionString(
                    c => c.Is(connectionString))
                )
                .Mappings(
                    m => m
                            .FluentMappings
                                .AddFromAssemblyOf<A>()
                            .Conventions
                                .AddFromAssemblyOf<A>()
                )
                .BuildSessionFactory();

where A is a type in the same assembly as UserTypeConvention<MyUserType> and MyUserType. However, Fluent NHibernate is not applying MyUserType to properties of type MyEnum on my domain objects. Instead, it is applying FluentNHibernate.Mapping.GenericEnumMapper<MyEnumType> to these properties.

What is going on?

agf
  • 171,228
  • 44
  • 289
  • 238
jason
  • 236,483
  • 35
  • 423
  • 525
  • Is your convention being hit if you debug it? Is it `public`? – James Gregory Oct 07 '10 at 11:45
  • @James Gregory: My convention is `public`. I overrode `UserTypeConvention.Accept` to see if it was being called. What I learned is that it is being called, but by the time my code reaches that point, Fluent NHibernate has already applied `GenericEnumMapper` to the property in question and thus the criteria `x => x.Type == typeof(MyEnum)` fails as `x.Type` is `FluentNHibernate.Mapping.GenericEnumMapper`. – jason Oct 07 '10 at 12:37
  • @James Gregory: Here is a small VS 2010 solution with a single failing test that replicates the issue: http://j.mp/bu7wQB – jason Oct 08 '10 at 07:44
  • Try moving your enum to where the properties are getting applied. – alexyorke Oct 15 '10 at 10:51
  • @alexy13: What do you mean? Also, to note, I will ultimately have many classes in my domain with a property that I would like to have be of type `MyEnum`. They will live in different namespaces. – jason Oct 15 '10 at 20:45
  • This might be a little messy, but you could create one shared namespace, and one singleton class to share enum's with other classes. – alexyorke Oct 15 '10 at 23:26

2 Answers2

1

For now I have solved this with:

public class MyEnumUserTypeConvention : UserTypeConvention<MyEnumUserType> {
    public override void Accept(IAcceptanceCriteria<IPropertyInspector> criteria) {
        // Fluent NHibernate is too eager in applying GenericEnumMapper
        // so our criteria is that it is already applied this type
        criteria.Expect(x => x.Type == typeof(GenericEnumMapper<MyEnum>));
    }

    public override void Apply(IPropertyInstance instance) {
        // we override Fluent NHibernate's application of GenericEnumMapper
        instance.CustomType<MyEnumUserType>();
    }
}

I think this should be thoroughly unnecessary. If someone told me this were a bug in Fluent NHibernate, that'd be fine. If someone gave me a good reason why Fluent NHibernate should be so eager in applying GenericEnumMapper that would be acceptable too.

jason
  • 236,483
  • 35
  • 423
  • 525
0

Ok i tried the following and I think it will works for you :
just overriede the Accept method in MyEnumUserTypeConvention class and do nothing inside it:

  public class MyEnumUserTypeConvention : UserTypeConvention<MyEnumUserType>
  {
    public override void Accept(FluentNHibernate.Conventions.AcceptanceCriteria.IAcceptanceCriteria<FluentNHibernate.Conventions.Inspections.IPropertyInspector> criteria)
    {
       ///Do nothing
    }
  }
Nour
  • 5,252
  • 3
  • 41
  • 66
  • This didn't work, my test still fails. The point is this _should_ work without having to override anything in `UserTypeConvention`. – jason Oct 15 '10 at 20:50
  • your test fails because you are checking that propertyType (status) should be equal to MyEnumUserType, but if you manually checked the type of propertyType, you see it is of type Nhibernate CustomType and its name is 'MyEnumUserType', and i think that what should be. – Nour Oct 16 '10 at 07:17
  • Okay, that's fine. You're right about that. But my point that this should work without having to override `UserTypeConvention.Accept` still remains. – jason Oct 16 '10 at 12:30
  • This will not work. Because there is no acceptance criteria, all properties are accepted which is clearly not desirable. – jason Oct 19 '10 at 17:20