Skip to content

Commit 35609a0

Browse files
committed
Modified ReferenceComponentMapping to pass visitors through to the underlying ExternalComponentMapping. Also modified ExternalComponentMapping to prevent it from running a visitor more than once.
This combination of changes should allow conventions to be applied to members of a component that was mapped via ComponentMap.
1 parent 4c96c43 commit 35609a0

File tree

4 files changed

+94
-0
lines changed

4 files changed

+94
-0
lines changed
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
using System;
2+
using System.Linq;
3+
using FluentNHibernate.Conventions;
4+
using FluentNHibernate.Conventions.AcceptanceCriteria;
5+
using FluentNHibernate.Conventions.Helpers;
6+
using FluentNHibernate.Conventions.Inspections;
7+
using FluentNHibernate.Conventions.Instances;
8+
using FluentNHibernate.Mapping;
9+
using FluentNHibernate.MappingModel.ClassBased;
10+
using FluentNHibernate.Specs.Conventions.Fixtures;
11+
using Machine.Specifications;
12+
13+
namespace FluentNHibernate.Specs.Conventions
14+
{
15+
public class when_a_property_convention_is_applied_to_a_component_mapping
16+
{
17+
Establish context = () =>
18+
{
19+
model = new FluentNHibernate.PersistenceModel();
20+
model.Add(new TestClassMap());
21+
model.Add(new MyComponentMap());
22+
model.Conventions.Add(new MyPropertyConvention());
23+
};
24+
25+
Because of = () =>
26+
mapping = model.BuildMappingFor<TestClass>();
27+
28+
It should_apply_the_convention_to_any_properties_that_match_the_acceptance_criteria = () =>
29+
mapping.Components.Single(x => x.Name == "Value").Properties.Single().Columns.Single().SqlType.ShouldEqual("money");
30+
31+
static FluentNHibernate.PersistenceModel model;
32+
static ClassMapping mapping;
33+
34+
private class TestClass
35+
{
36+
public int Id { get; set; }
37+
public MyComponent Value { get; set; }
38+
}
39+
40+
private class MyComponent
41+
{
42+
public decimal Price { get; set; }
43+
}
44+
45+
private class TestClassMap : ClassMap<TestClass>
46+
{
47+
public TestClassMap()
48+
{
49+
Id(x => x.Id);
50+
Component(x => x.Value);
51+
}
52+
}
53+
54+
private class MyComponentMap : ComponentMap<MyComponent>
55+
{
56+
public MyComponentMap()
57+
{
58+
Map(x => x.Price);
59+
}
60+
}
61+
62+
private class MyPropertyConvention : IPropertyConvention, IPropertyConventionAcceptance
63+
{
64+
public void Accept(IAcceptanceCriteria<IPropertyInspector> criteria)
65+
{
66+
criteria.Expect(x => x.Type == typeof(decimal));
67+
}
68+
69+
public void Apply(IPropertyInstance instance)
70+
{
71+
instance.CustomSqlType("money");
72+
}
73+
}
74+
}
75+
}

src/FluentNHibernate.Specs/FluentNHibernate.Specs.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,7 @@
135135
<Compile Include="Automapping\OverrideSpecs.cs" />
136136
<Compile Include="Conventions\BiDirectionalKeysSpecs.cs" />
137137
<Compile Include="Conventions\Fixtures\Parent.cs" />
138+
<Compile Include="Conventions\PropertyConventionSpecs.cs" />
138139
<Compile Include="PersistenceModel\Fixtures\UnionChildEntity.cs" />
139140
<Compile Include="PersistenceModel\Fixtures\UnionChildEntityMap.cs" />
140141
<Compile Include="PersistenceModel\Fixtures\UnionEntity.cs" />

src/FluentNHibernate/MappingModel/ClassBased/ExternalComponentMapping.cs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
using System;
2+
using FluentNHibernate.Visitors;
3+
using System.Collections.Generic;
24

35
namespace FluentNHibernate.MappingModel.ClassBased
46
{
@@ -15,5 +17,18 @@ public ExternalComponentMapping(ComponentType componentType)
1517
public ExternalComponentMapping(ComponentType componentType, AttributeStore underlyingStore)
1618
: base(componentType, underlyingStore)
1719
{}
20+
21+
private readonly IList<IMappingModelVisitor> previousVisitors = new List<IMappingModelVisitor>();
22+
23+
public override void AcceptVisitor(IMappingModelVisitor visitor)
24+
{
25+
// This external mapping might be shared amongst several ReferenceComponentMappings. Allowing a particular visitor to be applied to this component mapping
26+
// more than once can cause issues, so lets ensure that doesn't happen.
27+
if(previousVisitors.Contains(visitor))
28+
return;
29+
30+
previousVisitors.Add(visitor);
31+
base.AcceptVisitor(visitor);
32+
}
1833
}
1934
}

src/FluentNHibernate/MappingModel/ClassBased/ReferenceComponentMapping.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,9 @@ public ReferenceComponentMapping(ComponentType componentType, Member property, T
3232
public void AcceptVisitor(IMappingModelVisitor visitor)
3333
{
3434
visitor.ProcessComponent(this);
35+
36+
if(mergedComponent != null)
37+
visitor.Visit(mergedComponent);
3538
}
3639

3740
public bool IsSpecified(string name)

0 commit comments

Comments
 (0)