Skip to content
Browse files

Initial Automapping of inheritance.

git-svn-id: https://fluent-nhibernate.googlecode.com/svn/trunk@145 48f0ce17-cc52-0410-af8c-857c09b6549b
  • Loading branch information...
1 parent 794be94 commit 125c1041defef6f204ca9a22d961305e6b48448c Andrew Stewart committed Dec 11, 2008
View
33 src/FluentNHibernate.4.0.resharper
@@ -3,37 +3,4 @@
<Namespace>JetBrains.Annotations</Namespace>
<DefaultNamespace>JetBrains.Annotations</DefaultNamespace>
</CodeAnnotations>
- <SharedSolutionTemplateManager>
- <LiveTemplates>
- <Template uid="03229c49-6943-46b2-ba6a-400ac9550f85" text="[Test]&#xD;&#xA;public void $TESTNAME$()&#xD;&#xA;{&#xD;&#xA; $END$&#xD;&#xA;}" shortcut="pvt" description="New Test Case" reformat="true" shortenQualifiedReferences="true">
- <Context>
- <CSharpContext context="TypeMember" minimumLanguageVersion="2.0" />
- </Context>
- <Categories />
- <Variables>
- <Variable name="TESTNAME" expression="" initialRange="0" />
- </Variables>
- <CustomProperties />
- </Template>
- </LiveTemplates>
- <Surrounds />
- <FileTemplates>
- <Template uid="482e6087-caae-4484-b5cc-d7b56a938201" text="using NUnit.Framework;&#xD;&#xA;&#xD;&#xA;namespace $Testing_Namespace$&#xD;&#xA;{&#xD;&#xA; [TestFixture]&#xD;&#xA; public class $Test_Fixture_Name$&#xD;&#xA; {&#xD;&#xA; [Test]&#xD;&#xA; public void $Test_Name$()&#xD;&#xA; {&#xD;&#xA; $END$&#xD;&#xA; }&#xD;&#xA; }&#xD;&#xA;}" shortcut="" description="Test Fixture Class" reformat="true" shortenQualifiedReferences="true">
- <Context>
- <ProjectLanguageContext language="CSharp" />
- </Context>
- <Categories />
- <Variables>
- <Variable name="Testing_Namespace" expression="fileDefaultNamespace()" initialRange="0" />
- <Variable name="Test_Fixture_Name" expression="getFileNameWithoutExtension()" initialRange="0" />
- <Variable name="Test_Name" expression="" initialRange="0" />
- </Variables>
- <CustomProperties>
- <Property key="FileName" value="Class" />
- <Property key="Extension" value="cs" />
- <Property key="ValidateFileName" value="False" />
- </CustomProperties>
- </Template>
- </FileTemplates>
- </SharedSolutionTemplateManager>
</Configuration>
View
15 src/FluentNHibernate.Testing/AutoMap/AutoMapTests.cs
@@ -1,3 +1,5 @@
+using System;
+using System.Collections.Generic;
using System.Xml;
using FluentNHibernate;
using FluentNHibernate.AutoMap;
@@ -16,7 +18,7 @@ public class AutoMapTests
public void AutoMapIdentification()
{
var autoMapper = new AutoMapper(new Conventions());
- var map = autoMapper.Map<ExampleClass>();
+ var map = autoMapper.Map<ExampleClass>(new List<AutoMapType>());
Assert.IsNotNull(map);
@@ -31,7 +33,7 @@ public void AutoMapIdentification()
public void AutoMapVersion()
{
var autoMapper = new AutoMapper(new Conventions());
- var map = autoMapper.Map<ExampleClass>();
+ var map = autoMapper.Map<ExampleClass>(new List<AutoMapType>());
Assert.IsNotNull(map);
@@ -46,7 +48,7 @@ public void AutoMapVersion()
public void AutoMapProperty()
{
var autoMapper = new AutoMapper(new Conventions());
- var map = autoMapper.Map<ExampleClass>();
+ var map = autoMapper.Map<ExampleClass>(new List<AutoMapType>());
Assert.IsNotNull(map);
@@ -61,7 +63,7 @@ public void AutoMapProperty()
public void AutoMapIgnoreProperty()
{
var autoMapper = new AutoMapper(new Conventions());
- var map = autoMapper.Map<ExampleClass>();
+ var map = autoMapper.Map<ExampleClass>(new List<AutoMapType>());
Assert.IsNotNull(map);
@@ -76,7 +78,7 @@ public void AutoMapIgnoreProperty()
public void AutoMapManyToOne()
{
var autoMapper = new AutoMapper(new Conventions());
- var map = autoMapper.Map<ExampleClass>();
+ var map = autoMapper.Map<ExampleClass>(new List<AutoMapType>());
Assert.IsNotNull(map);
@@ -119,7 +121,7 @@ public void AutoMapManyToMany_ShouldRecognizeSet_BaseOnType()
public void AutoMapOneToMany()
{
var autoMapper = new AutoMapper(new Conventions());
- var map = autoMapper.Map<ExampleParentClass>();
+ var map = autoMapper.Map<ExampleParentClass>(new List<AutoMapType>());
Assert.IsNotNull(map);
@@ -128,6 +130,7 @@ public void AutoMapOneToMany()
var keyElement = (XmlElement)document.DocumentElement.SelectSingleNode("//bag");
keyElement.AttributeShouldEqual("name", "Examples");
}
+
}
}
View
1 src/FluentNHibernate.Testing/AutoMap/AutoMappingTester.cs
@@ -1,3 +1,4 @@
+using System;
using FluentNHibernate;
using FluentNHibernate.AutoMap;
using FluentNHibernate.Metadata;
View
65 src/FluentNHibernate.Testing/AutoMap/AutoPersistenceModelTests.cs
@@ -175,7 +175,7 @@ public void TestAutoMapPropertySetFindPrimaryKeyConvention()
{
var autoMapper = AutoPersistenceModel
.MapEntitiesFromAssemblyOf<ExampleClass>()
- .Where(t => t.Namespace == "FluentNHibernate.AutoMap.TestFixtures")
+ .Where(t => t == typeof(ExampleClass))
.WithConvention(c => c.FindIdentity = p => p.Name == p.DeclaringType.Name + "Id" );
autoMapper.Configure(cfg);
@@ -186,5 +186,68 @@ public void TestAutoMapPropertySetFindPrimaryKeyConvention()
.HasAttribute("column", "ExampleClassId");
}
+ [Test]
+ public void TestInheritanceMapping()
+ {
+ var autoMapper = AutoPersistenceModel
+ .MapEntitiesFromAssemblyOf<ExampleClass>()
+ .Where(t => t.Namespace == "FluentNHibernate.AutoMap.TestFixtures");
+
+ autoMapper.Configure(cfg);
+
+ var tester = new AutoMappingTester<ExampleClass>(autoMapper)
+ .Element("class/joined-subclass")
+ .HasAttribute("name", typeof(ExampleInheritedClass).AssemblyQualifiedName);
+
+ tester.Element("class/joined-subclass/key")
+ .HasAttribute("column", "ExampleClassId");
+ }
+
+ [Test]
+ public void TestInheritanceMappingProperties()
+ {
+ var autoMapper = AutoPersistenceModel
+ .MapEntitiesFromAssemblyOf<ExampleClass>()
+ .Where(t => t.Namespace == "FluentNHibernate.AutoMap.TestFixtures");
+
+ autoMapper.Configure(cfg);
+
+ var tester = new AutoMappingTester<ExampleClass>(autoMapper)
+ .Element("class/joined-subclass/property")
+ .HasAttribute("name", "ExampleProperty");
+ }
+
+ [Test]
+ public void TestInheritanceMappingDoesntIncludeBaseTypeProperties()
+ {
+ var autoMapper = AutoPersistenceModel
+ .MapEntitiesFromAssemblyOf<ExampleClass>()
+ .Where(t => t.Namespace == "FluentNHibernate.AutoMap.TestFixtures");
+
+ autoMapper.Configure(cfg);
+
+ new AutoMappingTester<ExampleClass>(autoMapper)
+ .Element("class/joined-subclass")
+ .ChildrenDontContainAttribute("name", "LineOne");
+ }
+
+ [Test]
+ public void TestInheritanceOverridingMappingProperties()
+ {
+ var autoMapper = AutoPersistenceModel
+ .MapEntitiesFromAssemblyOf<ExampleClass>()
+ .ForTypesThatDeriveFrom<ExampleClass>(t => t.JoinedSubClass<ExampleInheritedClass>("OverridenKey", p =>p.Map(c => c.ExampleProperty, "columnName")))
+ .Where(t => t.Namespace == "FluentNHibernate.AutoMap.TestFixtures");
+
+ autoMapper.Configure(cfg);
+
+ new AutoMappingTester<ExampleClass>(autoMapper).ToString();
+
+ var tester = new AutoMappingTester<ExampleClass>(autoMapper)
+ .Element("class/joined-subclass")
+ .ChildrenDontContainAttribute("name", "LineOne");
+ }
+
+
}
}
View
6 src/FluentNHibernate.Testing/AutoMap/TestFixtures.cs
@@ -17,14 +17,12 @@ public int CustomColumn
}
}
-/*
public class ExampleInheritedClass : ExampleClass
{
- public int Id { get; set; }
- public int ExampleInheritedClassId { get; set; }
public string ExampleProperty { get; set; }
+ public int SomeNumber{ get; set; }
}
-*/
+
public class ExampleClass
{
View
25 src/FluentNHibernate/AutoMap/AutoMap.cs
@@ -8,6 +8,8 @@ namespace FluentNHibernate.AutoMap
public class AutoMap<T> : ClassMap<T>
{
private IList<PropertyInfo> propertiesMapped = new List<PropertyInfo>();
+ private Dictionary<Type, object> joinedSubClasses = new Dictionary<Type, object>();
+
public IList<PropertyInfo> PropertiesMapped
{
get { return propertiesMapped; }
@@ -78,5 +80,28 @@ public override VersionPart Version(System.Linq.Expressions.Expression<Func<T, o
propertiesMapped.Add(ReflectionHelper.GetProperty(expression));
return base.Version(expression);
}
+
+ public AutoJoinedSubClassPart<TSubclass> JoinedSubClass<TSubclass>(string keyColumn, Action<AutoJoinedSubClassPart<TSubclass>> action)
+ {
+ var genericType = typeof(AutoJoinedSubClassPart<>).MakeGenericType(typeof(TSubclass));
+ var joinedclass = (AutoJoinedSubClassPart<TSubclass>)Activator.CreateInstance(genericType, keyColumn);
+ action(joinedclass);
+ AddPart(joinedclass);
+ joinedSubClasses.Add(typeof(TSubclass), joinedclass);
+ return joinedclass;
+
+ }
+
+ public object JoinedSubClass(Type type, string keyColumn)
+ {
+ if (joinedSubClasses.ContainsKey(type))
+ return joinedSubClasses[type];
+
+
+ var genericType = typeof (AutoJoinedSubClassPart<>).MakeGenericType(type);
+ var joinedclass = (IMappingPart)Activator.CreateInstance(genericType, keyColumn);
+ AddPart(joinedclass);
+ return joinedclass;
+ }
}
}
View
3 src/FluentNHibernate/AutoMap/AutoMapIdentity.cs
@@ -16,6 +16,9 @@ public AutoMapIdentity(Conventions conventions)
public bool MapsProperty(PropertyInfo property)
{
+ if (property.ReflectedType.BaseType != typeof(object))
+ return false;
+
return conventions.FindIdentity.Invoke(property);
}
View
3 src/FluentNHibernate/AutoMap/AutoMapVersion.cs
@@ -17,6 +17,9 @@ public AutoMapVersion(Conventions conventions)
public bool MapsProperty(PropertyInfo property)
{
+ if (property.ReflectedType.BaseType != typeof(object))
+ return false;
+
return findPropertyconvention.Invoke(property);
}
View
25 src/FluentNHibernate/AutoMap/AutoMapper.cs
@@ -9,6 +9,7 @@ namespace FluentNHibernate.AutoMap
public class AutoMapper
{
private readonly List<IAutoMapper> _mappingRules;
+ private List<AutoMapType> mappingTypes;
public AutoMapper(Conventions conventions)
{
@@ -25,9 +26,27 @@ public AutoMapper(Conventions conventions)
public AutoMap<T> MergeMap<T>(AutoMap<T> map)
{
+ if (mappingTypes != null)
+ {
+ foreach (var inheritedClass in mappingTypes.Where(q => q.Type.BaseType == typeof (T)))
+ {
+ object joinedClass = map.JoinedSubClass(inheritedClass.Type, typeof(T).Name + "Id");
+ var method = this.GetType().GetMethod("mapEverythingInClass");
+ var genericMethod = method.MakeGenericMethod(inheritedClass.Type);
+ genericMethod.Invoke(this, new[] {joinedClass});
+ inheritedClass.IsMapped = true;
+ }
+ }
+
+ mapEverythingInClass(map);
+ return map;
+ }
+
+ public void mapEverythingInClass<T>(AutoMap<T> map)
+ {
foreach (var property in typeof(T).GetProperties())
{
- if (!property.PropertyType.IsEnum && property.GetIndexParameters().Length == 0)
+ if ((property.DeclaringType == typeof(T)) && !property.PropertyType.IsEnum && property.GetIndexParameters().Length == 0)
{
foreach (var rule in _mappingRules)
{
@@ -42,12 +61,12 @@ public AutoMap<T> MergeMap<T>(AutoMap<T> map)
}
}
}
- return map;
}
- public AutoMap<T> Map<T>()
+ public AutoMap<T> Map<T>(List<AutoMapType> types)
{
var classMap = (AutoMap<T>)Activator.CreateInstance(typeof(AutoMap<T>));
+ mappingTypes = types;
return MergeMap(classMap);
}
}
View
62 src/FluentNHibernate/AutoMap/AutoPersistenceModel.cs
@@ -1,16 +1,17 @@
using System;
+using System.Collections.Generic;
using System.Reflection;
-using FluentNHibernate;
using FluentNHibernate.Mapping;
namespace FluentNHibernate.AutoMap
{
public class AutoPersistenceModel : PersistenceModel
{
- private readonly AutoMapper autoMap;
+ private readonly AutoMapper autoMapper;
private Assembly assemblyContainingMaps;
private Assembly entityAssembly;
private Func<Type, bool> shouldIncludeType;
+ private readonly List<AutoMapType> mappingTypes = new List<AutoMapType>();
public AutoPersistenceModel WithConvention(Conventions convention)
{
@@ -50,20 +51,27 @@ public override void Configure(NHibernate.Cfg.Configuration configuration)
foreach (var type in entityAssembly.GetTypes())
{
- if (shouldIncludeType!= null)
+ if (shouldIncludeType != null)
{
if (!shouldIncludeType.Invoke(type))
continue;
}
+ mappingTypes.Add(new AutoMapType(type));
+ }
- if (type.IsClass)
+ foreach (var type in mappingTypes)
+ {
+ if (type.Type.IsClass)
{
- var mapping = FindMapping(type);
-
- if (mapping != null)
- MergeMap(type, mapping);
- else
- AddMapping(type);
+ if (!type.IsMapped)
+ {
+ var mapping = FindMapping(type.Type);
+
+ if (mapping != null)
+ MergeMap(type.Type, mapping);
+ else
+ AddMapping(type.Type);
+ }
}
}
@@ -72,32 +80,39 @@ public override void Configure(NHibernate.Cfg.Configuration configuration)
#region Configuation Helpers
- private object AddMapping(Type type)
+ private void AddMapping(Type type)
{
+ Type typeToMap = GetTypeToMap(type);
var mapping = InvocationHelper.InvokeGenericMethodWithDynamicTypeArguments(
- autoMap, a => a.Map<object>(), null, type);
+ autoMapper, a => a.Map<object>(mappingTypes), new object[] {mappingTypes}, typeToMap);
addMapping((IMapping)mapping);
- return mapping;
+ }
+
+ private Type GetTypeToMap(Type type)
+ {
+ return type.BaseType == typeof(object) ? type : type.BaseType;
}
private void MergeMap(Type type, object mapping)
{
+ Type typeToMap = GetTypeToMap(type);
InvocationHelper.InvokeGenericMethodWithDynamicTypeArguments(
- autoMap, a => a.MergeMap<object>(null), new[] { mapping }, type);
+ autoMapper, a => a.MergeMap<object>(null), new[] { mapping }, typeToMap);
}
private object FindMapping(Type type)
{
+ Type typeToMap = GetTypeToMap(type);
var mapping = InvocationHelper.InvokeGenericMethodWithDynamicTypeArguments(
- this, a => a.FindMapping<object>(), null, type);
+ this, a => a.FindMapping<object>(), null, typeToMap);
return mapping;
}
#endregion
public AutoPersistenceModel()
{
- autoMap = new AutoMapper(Conventions);
+ autoMapper = new AutoMapper(Conventions);
}
/// <summary>
@@ -107,12 +122,12 @@ public AutoPersistenceModel()
public AutoPersistenceModel(Assembly mapAssembly)
{
addMappingsFromAssembly(mapAssembly);
- autoMap = new AutoMapper(Conventions);
+ autoMapper = new AutoMapper(Conventions);
}
public AutoPersistenceModel AutoMap<T>()
{
- addMapping(autoMap.Map<T>());
+ addMapping(autoMapper.Map<T>(mappingTypes));
return this;
}
@@ -141,4 +156,15 @@ public AutoPersistenceModel ForTypesThatDeriveFrom<T>(Action<AutoMap<T>> populat
return this;
}
}
+
+ public class AutoMapType
+ {
+ public AutoMapType(Type type)
+ {
+ Type = type;
+ }
+
+ public Type Type { get; set;}
+ public bool IsMapped { get; set; }
+ }
}
View
3 src/FluentNHibernate/FluentNHibernate.csproj
@@ -57,9 +57,11 @@
<Link>CommonAssemblyInfo.cs</Link>
</Compile>
<Compile Include="Accessor.cs" />
+ <Compile Include="AutoMap\AutoJoinedSubClassPart.cs" />
<Compile Include="AutoMap\AutoMap.cs" />
<Compile Include="AutoMap\AutoMapColumn.cs" />
<Compile Include="AutoMap\AutoMapIdentity.cs" />
+ <Compile Include="AutoMap\AutoMapJoinedSubClass.cs" />
<Compile Include="AutoMap\AutoMapManyToOne.cs" />
<Compile Include="AutoMap\AutoMapOneToMany.cs" />
<Compile Include="AutoMap\AutoMapper.cs" />
@@ -68,6 +70,7 @@
<Compile Include="AutoMap\ConventionBuilder.cs" />
<Compile Include="AutoMap\ExpressionBuilder.cs" />
<Compile Include="AutoMap\IAutoMapper.cs" />
+ <Compile Include="AutoMap\PropertyInfoHelper.cs" />
<Compile Include="AutoMap\ManyToManyAutoMapper.cs" />
<Compile Include="Cache.cs" />
<Compile Include="Cfg\PersistenceConfiguration.cs" />

0 comments on commit 125c104

Please sign in to comment.
Something went wrong with that request. Please try again.