Skip to content

Commit

Permalink
Initial Automapping of inheritance.
Browse files Browse the repository at this point in the history
git-svn-id: https://fluent-nhibernate.googlecode.com/svn/trunk@145 48f0ce17-cc52-0410-af8c-857c09b6549b
  • Loading branch information
Andrew Stewart committed Dec 11, 2008
1 parent 794be94 commit 125c104
Show file tree
Hide file tree
Showing 11 changed files with 176 additions and 65 deletions.
33 changes: 0 additions & 33 deletions src/FluentNHibernate.4.0.resharper
Expand Up @@ -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>
15 changes: 9 additions & 6 deletions src/FluentNHibernate.Testing/AutoMap/AutoMapTests.cs
@@ -1,3 +1,5 @@
using System;
using System.Collections.Generic;
using System.Xml;
using FluentNHibernate;
using FluentNHibernate.AutoMap;
Expand All @@ -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);

Expand All @@ -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);

Expand All @@ -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);

Expand All @@ -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);

Expand All @@ -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);

Expand Down Expand Up @@ -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);

Expand All @@ -128,6 +130,7 @@ public void AutoMapOneToMany()
var keyElement = (XmlElement)document.DocumentElement.SelectSingleNode("//bag");
keyElement.AttributeShouldEqual("name", "Examples");
}

}
}

1 change: 1 addition & 0 deletions src/FluentNHibernate.Testing/AutoMap/AutoMappingTester.cs
@@ -1,3 +1,4 @@
using System;
using FluentNHibernate;
using FluentNHibernate.AutoMap;
using FluentNHibernate.Metadata;
Expand Down
Expand Up @@ -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);
Expand All @@ -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");
}


}
}
6 changes: 2 additions & 4 deletions src/FluentNHibernate.Testing/AutoMap/TestFixtures.cs
Expand Up @@ -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
{
Expand Down
25 changes: 25 additions & 0 deletions src/FluentNHibernate/AutoMap/AutoMap.cs
Expand Up @@ -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; }
Expand Down Expand Up @@ -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;
}
}
}
3 changes: 3 additions & 0 deletions src/FluentNHibernate/AutoMap/AutoMapIdentity.cs
Expand Up @@ -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);
}

Expand Down
3 changes: 3 additions & 0 deletions src/FluentNHibernate/AutoMap/AutoMapVersion.cs
Expand Up @@ -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);
}

Expand Down
25 changes: 22 additions & 3 deletions src/FluentNHibernate/AutoMap/AutoMapper.cs
Expand Up @@ -9,6 +9,7 @@ namespace FluentNHibernate.AutoMap
public class AutoMapper
{
private readonly List<IAutoMapper> _mappingRules;
private List<AutoMapType> mappingTypes;

public AutoMapper(Conventions conventions)
{
Expand All @@ -24,10 +25,28 @@ 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)
{
Expand All @@ -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);
}
}
Expand Down

0 comments on commit 125c104

Please sign in to comment.