I'm new to Fluent NHibernate but was drawn by the Automapping and otherwise great featureset of the platform. I'm having trouble with getting an ObservableCollection setup, I've scoured the web and tried many different things and all of them have led me back to the same error:
FluentNHibernate.Cfg.FluentConfigurationException: An invalid or incomplete configuration was used while creating a SessionFactory. Check PotentialReasons collection, and InnerException for more detail.
---> FluentNHibernate.Cfg.FluentConfigurationException: An invalid or incomplete configuration was used while creating a SessionFactory. Check PotentialReasons collection, and InnerException for more detail.
---> System.ArgumentException: Cannot create an instance of FluentNHibernate.Automapping.AutoMapping`1[uNhAddIns.WPF.Collections.Types.ObservableListType`1[T]] because Type.ContainsGenericParameters is true.
at System.RuntimeType.CreateInstanceCheckThis()
at System.RuntimeType.CreateInstanceImpl(BindingFlags bindingAttr, Binder binder, Object[] args, CultureInfo culture, Object[] activationAttributes)
at System.Activator.CreateInstance(Type type, BindingFlags bindingAttr, Binder binder, Object[] args, CultureInfo culture, Object[] activationAttributes)
at FluentNHibernate.Automapping.AutoMapper.ApplyOverrides(Type classType, IList`1 mappedMembers, ClassMappingBase mapping) in d:\Builds\FluentNH-v1.x-nh3\src\FluentNHibernate\Automapping\AutoMapper.cs:line 28
at FluentNHibernate.Automapping.AutoMapper.MergeMap(Type classType, ClassMappingBase mapping, IList`1 mappedMembers) in d:\Builds\FluentNH-v1.x-nh3\src\FluentNHibernate\Automapping\AutoMapper.cs:line 41
at FluentNHibernate.Automapping.AutoMapper.Map(Type classType, List`1 types) in d:\Builds\FluentNH-v1.x-nh3\src\FluentNHibernate\Automapping\AutoMapper.cs:line 176
at FluentNHibernate.Automapping.AutoPersistenceModel.AddMapping(Type type) in d:\Builds\FluentNH-v1.x-nh3\src\FluentNHibernate\Automapping\AutoPersistenceModel.cs:line 185
at FluentNHibernate.Automapping.AutoPersistenceModel.CompileMappings() in d:\Builds\FluentNH-v1.x-nh3\src\FluentNHibernate\Automapping\AutoPersistenceModel.cs:line 149
at FluentNHibernate.Automapping.AutoPersistenceModel.Configure(Configuration configuration) in d:\Builds\FluentNH-v1.x-nh3\src\FluentNHibernate\Automapping\AutoPersistenceModel.cs:line 175
at FluentNHibernate.Cfg.AutoMappingsContainer.Apply(Configuration cfg) in d:\Builds\FluentNH-v1.x-nh3\src\FluentNHibernate\Cfg\AutoMappingsContainer.cs:line 84
at FluentNHibernate.Cfg.MappingConfiguration.Apply(Configuration cfg) in d:\Builds\FluentNH-v1.x-nh3\src\FluentNHibernate\Cfg\MappingConfiguration.cs:line 66
at FluentNHibernate.Cfg.FluentConfiguration.BuildConfiguration() in d:\Builds\FluentNH-v1.x-nh3\src\FluentNHibernate\Cfg\FluentConfiguration.cs:line 128
--- End of inner exception stack trace ---
at FluentNHibernate.Cfg.FluentConfiguration.BuildConfiguration() in d:\Builds\FluentNH-v1.x-nh3\src\FluentNHibernate\Cfg\FluentConfiguration.cs:line 139
at FluentNHibernate.Cfg.FluentConfiguration.BuildSessionFactory() in d:\Builds\FluentNH-v1.x-nh3\src\FluentNHibernate\Cfg\FluentConfiguration.cs:line 108
--- End of inner exception stack trace ---
at FluentNHibernate.Cfg.FluentConfiguration.BuildSessionFactory() in d:\Builds\FluentNH-v1.x-nh3\src\FluentNHibernate\Cfg\FluentConfiguration.cs:line 113
at ToDoIt2.Model.Document.<Initialize>b__0() in C:\data\svn\WPF\vs2010\ToDoIt2\Application\Model\Document.cs:line 54
at ToDoIt2.App.DisplayException(NoArgsDelegate z) in C:\data\svn\WPF\vs2010\ToDoIt2\Application\App.xaml.cs:line 66
This being the applicable line:
---> System.ArgumentException: Cannot create an instance of
FluentNHibernate.Automapping.AutoMapping`1[uNhAddIns.WPF.Collections.Types.ObservableListType`1[T]]
because Type.ContainsGenericParameters is true.
Here is the class I am trying to map:
public class Item {
public virtual int ItemID { get; set; }
public virtual string Title { get; set; }
public virtual ObservableListType<string> Children { get; set; }
}
Using uNhAddIns.WPF.Collections.Types.ObservableListType from uNhAddIns.
Here is my AutoMapping:
this.FluentConfig = Fluently.Configure()
.Mappings(m => m.AutoMappings
.Add(AutoMap
.Assemblies(new ToDoIt2.DB.AutoMapping(),
Assembly.GetExecutingAssembly(),
Assembly.GetAssembly(typeof(ObservableListType<>))
)
.IgnoreBase<pklib.DataObject>()
.Conventions.Add<myPrimaryKeyConvention>()
.Conventions.Add<myForeignKeyConvention>()
));
Answer From @Diego
Domain Entity needed to change to:
public class Item {
public virtual int ItemID { get; set; }
public virtual string Title { get; set; }
public virtual ICollection<string> Children { get; set; }
}
Fluent Configuration Changed To:
this.FluentConfig = Fluently.Configure()
.ExposeConfiguration(cfg => cfg.SetProperty(NHibernate.Cfg.Environment.CollectionTypeFactoryClass,
typeof(WpfCollectionTypeFactory).AssemblyQualifiedName))
.Mappings(m => m.AutoMappings
.Add(AutoMap
.Assemblies(new ToDoIt2.DB.AutoMapping(),
Assembly.GetExecutingAssembly(),
Assembly.GetAssembly(typeof(ObservableListType<>))
)
.IgnoreBase<pklib.DataObject>()
.Conventions.Add<myPrimaryKeyConvention>()
.Conventions.Add<myForeignKeyConvention>()
));
You are not supposed to directly use ObservableListType in your classes and mappings (use
ICollection<T>
,IList<T>
, etc)Instead, you need to use
WpfCollectionTypeFactory
as the collection type factory.In XML configuration, this is done by setting
collectiontype.factory_class="uNhAddIns.WPF.Collections.WpfCollectionTypeFactory, uNhAddIns.WPF"
.I don't know if Fluent has any shortcuts, but you can use the following: