diff --git a/src/FluentNHibernate.Testing/FluentInterfaceTests/BaseModelFixture.cs b/src/FluentNHibernate.Testing/FluentInterfaceTests/BaseModelFixture.cs index 248ba8be3..27121dd9f 100644 --- a/src/FluentNHibernate.Testing/FluentInterfaceTests/BaseModelFixture.cs +++ b/src/FluentNHibernate.Testing/FluentInterfaceTests/BaseModelFixture.cs @@ -40,7 +40,7 @@ public abstract class BaseModelFixture protected ModelTester, SubclassMapping> SubclassMapForSubclass() { - return new ModelTester, SubclassMapping>(() => new SubclassMap(), x => (SubclassMapping)x.GetSubclassMapping(new SubclassMapping())); + return new ModelTester, SubclassMapping>(() => new SubclassMap(), x => (SubclassMapping)((IIndeterminateSubclassMappingProvider)x).GetSubclassMapping(new SubclassMapping())); } protected ModelTester, JoinedSubclassMapping> JoinedSubclass() @@ -50,7 +50,7 @@ public abstract class BaseModelFixture protected ModelTester, JoinedSubclassMapping> SubclassMapForJoinedSubclass() { - return new ModelTester, JoinedSubclassMapping>(() => new SubclassMap(), x => (JoinedSubclassMapping)x.GetSubclassMapping(new JoinedSubclassMapping())); + return new ModelTester, JoinedSubclassMapping>(() => new SubclassMap(), x => (JoinedSubclassMapping)((IIndeterminateSubclassMappingProvider)x).GetSubclassMapping(new JoinedSubclassMapping())); } protected ModelTester, ComponentMapping> Component() diff --git a/src/FluentNHibernate.Testing/FluentInterfaceTests/SubclassMapForSubclassSubPartModelGenerationTests.cs b/src/FluentNHibernate.Testing/FluentInterfaceTests/SubclassMapForSubclassSubPartModelGenerationTests.cs index 6b2b8102a..dac40c297 100644 --- a/src/FluentNHibernate.Testing/FluentInterfaceTests/SubclassMapForSubclassSubPartModelGenerationTests.cs +++ b/src/FluentNHibernate.Testing/FluentInterfaceTests/SubclassMapForSubclassSubPartModelGenerationTests.cs @@ -1,4 +1,6 @@ +using System; using System.Linq; +using FluentNHibernate.Mapping; using FluentNHibernate.Testing.DomainModel; using FluentNHibernate.Testing.DomainModel.Mapping; using NUnit.Framework; @@ -16,6 +18,44 @@ public void ComponentShouldAddToModelComponentsCollection() .ModelShouldMatch(x => x.Components.Count().ShouldEqual(1)); } + [Test] + public void ComponentWithPropertiesShouldAddToModelComponentsCollection() + { + var classMap = new ClassMap(); + + classMap.Id(x => x.Id); + + var subclassMap = new SubclassMap(); + + subclassMap.Component(x => x.Component, c => c.Map(x => x.Name)); + + var model = new PersistenceModel(); + + model.Add(classMap); + model.Add(subclassMap); + + model.BuildMappings() + .First() + .Classes.First() + .Subclasses.First() + .Components.Count().ShouldEqual(1); + } + + private class Parent + { + public int Id { get; set; } + } + + private class Child : Parent + { + public Component Component { get; set; } + } + + private class Component + { + public string Name { get; set; } + } + [Test] public void DynamicComponentShouldAddToModelComponentsCollection() { diff --git a/src/FluentNHibernate/Mapping/ComponentPart.cs b/src/FluentNHibernate/Mapping/ComponentPart.cs index 705c65c4b..9dc9aaf2f 100644 --- a/src/FluentNHibernate/Mapping/ComponentPart.cs +++ b/src/FluentNHibernate/Mapping/ComponentPart.cs @@ -1,27 +1,40 @@ using System; using System.Linq.Expressions; using System.Reflection; +using FluentNHibernate.MappingModel; using FluentNHibernate.MappingModel.ClassBased; namespace FluentNHibernate.Mapping { public class ComponentPart : ComponentPartBase { + private readonly Type entity; private readonly AccessStrategyBuilder> access; + private readonly AttributeStore attributes; public ComponentPart(Type entity, PropertyInfo property) - : this(new ComponentMapping { ContainingEntityType = entity }, property.Name) - { } + : this(entity, property.Name, new AttributeStore()) + {} - private ComponentPart(ComponentMapping mapping, string propertyName) - : base(mapping, propertyName) + private ComponentPart(Type entity, string propertyName, AttributeStore underlyingStore) + : base(underlyingStore, propertyName) { - access = new AccessStrategyBuilder>(this, value => mapping.Access = value); + attributes = new AttributeStore(underlyingStore); + access = new AccessStrategyBuilder>(this, value => attributes.Set(x => x.Access, value)); + this.entity = entity; Insert(); Update(); } + protected override IComponentMapping CreateComponentMappingRoot(AttributeStore store) + { + return new ComponentMapping(store) + { + ContainingEntityType = entity + }; + } + /// /// Set the access and naming strategy for this component. /// @@ -65,7 +78,7 @@ public new ComponentPart Update() public ComponentPart LazyLoad() { - mapping.Lazy = nextBool; + attributes.Set(x => x.Lazy, nextBool); nextBool = true; return this; } diff --git a/src/FluentNHibernate/Mapping/ComponentPartBase.cs b/src/FluentNHibernate/Mapping/ComponentPartBase.cs index a696ebb55..5badcde5f 100644 --- a/src/FluentNHibernate/Mapping/ComponentPartBase.cs +++ b/src/FluentNHibernate/Mapping/ComponentPartBase.cs @@ -12,18 +12,22 @@ public abstract class ComponentPartBase : ClasslikeMapBase, IComponentMapp { private readonly string propertyName; private readonly AccessStrategyBuilder> access; - protected ComponentMappingBase mapping; protected bool nextBool = true; + private readonly AttributeStore attributes; - protected ComponentPartBase(ComponentMappingBase mapping, string propertyName) + protected ComponentPartBase(AttributeStore underlyingStore, string propertyName) { - this.mapping = mapping; - access = new AccessStrategyBuilder>(this, value => mapping.Access = value); + attributes = new AttributeStore(underlyingStore); + access = new AccessStrategyBuilder>(this, value => attributes.Set(x => x.Access, value)); this.propertyName = propertyName; } + protected abstract IComponentMapping CreateComponentMappingRoot(AttributeStore store); + IComponentMapping IComponentMappingProvider.GetComponentMapping() { + var mapping = CreateComponentMappingRoot(attributes.CloneInner()); + mapping.Name = propertyName; foreach (var property in properties) @@ -62,11 +66,11 @@ public ComponentPartBase ParentReference(Expression> exp) private ComponentPartBase ParentReference(PropertyInfo property) { - mapping.Parent = new ParentMapping + attributes.Set(x => x.Parent, new ParentMapping { Name = property.Name, ContainingEntityType = typeof(T) - }; + }); return this; } @@ -82,8 +86,8 @@ public ComponentPartBase Not public ComponentPartBase ReadOnly() { - mapping.Insert = !nextBool; - mapping.Update = !nextBool; + attributes.Set(x => x.Insert, !nextBool); + attributes.Set(x => x.Update, !nextBool); nextBool = true; return this; @@ -91,28 +95,28 @@ public ComponentPartBase ReadOnly() public ComponentPartBase Insert() { - mapping.Insert = nextBool; + attributes.Set(x => x.Insert, nextBool); nextBool = true; return this; } public ComponentPartBase Update() { - mapping.Update = nextBool; + attributes.Set(x => x.Update, nextBool); nextBool = true; return this; } public ComponentPartBase Unique() { - mapping.Unique = nextBool; + attributes.Set(x => x.Unique, nextBool); nextBool = true; return this; } public ComponentPartBase OptimisticLock() { - mapping.OptimisticLock = nextBool; + attributes.Set(x => x.OptimisticLock, nextBool); nextBool = true; return this; } diff --git a/src/FluentNHibernate/Mapping/DynamicComponentPart.cs b/src/FluentNHibernate/Mapping/DynamicComponentPart.cs index a8ca51df0..436cc9365 100644 --- a/src/FluentNHibernate/Mapping/DynamicComponentPart.cs +++ b/src/FluentNHibernate/Mapping/DynamicComponentPart.cs @@ -1,24 +1,35 @@ using System; using System.Linq.Expressions; using System.Reflection; +using FluentNHibernate.MappingModel; using FluentNHibernate.MappingModel.ClassBased; namespace FluentNHibernate.Mapping { public class DynamicComponentPart : ComponentPartBase { + private readonly Type entity; private readonly AccessStrategyBuilder> access; + private readonly AttributeStore attributes; public DynamicComponentPart(Type entity, PropertyInfo property) - : this(new DynamicComponentMapping { ContainingEntityType = entity }, property.Name) + : this(entity, property.Name, new AttributeStore()) {} - private DynamicComponentPart(DynamicComponentMapping mapping, string propertyName) - : base(mapping, propertyName) + private DynamicComponentPart(Type entity, string propertyName, AttributeStore underlyingStore) + : base(underlyingStore, propertyName) { - access = new AccessStrategyBuilder>(this, value => mapping.Access = value); + this.entity = entity; + attributes = new AttributeStore(underlyingStore); + access = new AccessStrategyBuilder>(this, value => attributes.Set(x => x.Access, value)); + } - this.mapping = mapping; + protected override IComponentMapping CreateComponentMappingRoot(AttributeStore store) + { + return new DynamicComponentMapping(store) + { + ContainingEntityType = entity + }; } /// diff --git a/src/FluentNHibernate/Mapping/SubclassMap.cs b/src/FluentNHibernate/Mapping/SubclassMap.cs index 2f0fb5157..025931cab 100644 --- a/src/FluentNHibernate/Mapping/SubclassMap.cs +++ b/src/FluentNHibernate/Mapping/SubclassMap.cs @@ -25,7 +25,7 @@ public SubclassMap Not } } - public ISubclassMapping GetSubclassMapping(ISubclassMapping mapping) + ISubclassMapping IIndeterminateSubclassMappingProvider.GetSubclassMapping(ISubclassMapping mapping) { GenerateNestedSubclasses(mapping); diff --git a/src/FluentNHibernate/MappingModel/ClassBased/ComponentMapping.cs b/src/FluentNHibernate/MappingModel/ClassBased/ComponentMapping.cs index cf3099d65..3c2165bf8 100644 --- a/src/FluentNHibernate/MappingModel/ClassBased/ComponentMapping.cs +++ b/src/FluentNHibernate/MappingModel/ClassBased/ComponentMapping.cs @@ -11,7 +11,7 @@ public ComponentMapping() : this(new AttributeStore()) {} - private ComponentMapping(AttributeStore store) + public ComponentMapping(AttributeStore store) : base(store) { attributes = new AttributeStore(store); diff --git a/src/FluentNHibernate/MappingModel/ClassBased/DynamicComponentMapping.cs b/src/FluentNHibernate/MappingModel/ClassBased/DynamicComponentMapping.cs index 85e7639ca..c37955745 100644 --- a/src/FluentNHibernate/MappingModel/ClassBased/DynamicComponentMapping.cs +++ b/src/FluentNHibernate/MappingModel/ClassBased/DynamicComponentMapping.cs @@ -11,7 +11,7 @@ public DynamicComponentMapping() : this(new AttributeStore()) { } - private DynamicComponentMapping(AttributeStore store) + public DynamicComponentMapping(AttributeStore store) : base(store) { attributes = new AttributeStore(store); diff --git a/src/FluentNHibernate/MappingModel/ClassBased/IComponentMapping.cs b/src/FluentNHibernate/MappingModel/ClassBased/IComponentMapping.cs index 85e624789..be97fc53a 100644 --- a/src/FluentNHibernate/MappingModel/ClassBased/IComponentMapping.cs +++ b/src/FluentNHibernate/MappingModel/ClassBased/IComponentMapping.cs @@ -13,7 +13,7 @@ public interface IComponentMapping bool Update { get; set; } string Access { get; set; } Type ContainingEntityType { get; } - string Name { get; } + string Name { get; set; } PropertyInfo PropertyInfo { get; } Type Type { get; } bool Lazy { get; } @@ -25,5 +25,11 @@ public interface IComponentMapping IEnumerable Components { get; } IEnumerable OneToOnes { get; } IEnumerable Anys { get; } + void AddProperty(PropertyMapping mapping); + void AddComponent(IComponentMapping mapping); + void AddOneToOne(OneToOneMapping mapping); + void AddCollection(ICollectionMapping mapping); + void AddReference(ManyToOneMapping mapping); + void AddAny(AnyMapping mapping); } } \ No newline at end of file diff --git a/src/FluentNHibernate/MappingModel/ClassBased/ISubclassMapping.cs b/src/FluentNHibernate/MappingModel/ClassBased/ISubclassMapping.cs index 85d0e0b8a..4a4d542f2 100644 --- a/src/FluentNHibernate/MappingModel/ClassBased/ISubclassMapping.cs +++ b/src/FluentNHibernate/MappingModel/ClassBased/ISubclassMapping.cs @@ -9,6 +9,7 @@ public interface ISubclassMapping : IMappingBase string Name { get; set; } Type Type { get; } IEnumerable Subclasses { get; } + IEnumerable Components { get; } void OverrideAttributes(AttributeStore store); void AddProperty(PropertyMapping mapping); void AddComponent(IComponentMapping mapping);