Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
100 changes: 57 additions & 43 deletions src/FluentNHibernate/Mapping/ClassMap.cs
Original file line number Diff line number Diff line change
Expand Up @@ -618,56 +618,70 @@ ClassMapping IMappingProvider.GetClassMapping()
mapping.Set(x => x.Type, Layer.Defaults, typeof(T));
mapping.Set(x => x.Name, Layer.Defaults, typeof(T).AssemblyQualifiedName);

foreach (var property in providers.Properties)
mapping.AddProperty(property.GetPropertyMapping());

foreach (var component in providers.Components)
mapping.AddComponent(component.GetComponentMapping());

if (providers.Version != null)
mapping.Set(x => x.Version, Layer.Defaults, providers.Version.GetVersionMapping());

foreach (var oneToOne in providers.OneToOnes)
mapping.AddOneToOne(oneToOne.GetOneToOneMapping());

foreach (var collection in providers.Collections)
mapping.AddCollection(collection.GetCollectionMapping());

foreach (var reference in providers.References)
mapping.AddReference(reference.GetManyToOneMapping());

foreach (var any in providers.Anys)
mapping.AddAny(any.GetAnyMapping());

foreach (var subclass in providers.Subclasses.Values)
mapping.AddSubclass(subclass.GetSubclassMapping());

foreach (var join in providers.Joins)
mapping.AddJoin(join.GetJoinMapping());

if (providers.Discriminator != null)
mapping.Set(x => x.Discriminator, Layer.Defaults, providers.Discriminator.GetDiscriminatorMapping());
mapping.Set(x => x.Version, Layer.Defaults, providers.Version.GetVersionMapping());

foreach (var provider in providers.OrderedProviders) {
var x = provider.Item2;
switch (provider.Item1) {
case MappingProviderStore.ProviderType.Property:
mapping.AddProperty(((IPropertyMappingProvider) x).GetPropertyMapping());
break;
case MappingProviderStore.ProviderType.Component:
mapping.AddComponent(((IComponentMappingProvider) x).GetComponentMapping());
break;
case MappingProviderStore.ProviderType.OneToOne:
mapping.AddOneToOne(((IOneToOneMappingProvider) x).GetOneToOneMapping());
break;
case MappingProviderStore.ProviderType.Subclass:
mapping.AddSubclass(((ISubclassMappingProvider) x).GetSubclassMapping());
break;
case MappingProviderStore.ProviderType.Collection:
mapping.AddCollection(((ICollectionMappingProvider) x).GetCollectionMapping());
break;
case MappingProviderStore.ProviderType.ManyToOne:
mapping.AddReference(((IManyToOneMappingProvider) x).GetManyToOneMapping());
break;
case MappingProviderStore.ProviderType.Any:
mapping.AddAny(((IAnyMappingProvider) x).GetAnyMapping());
break;
case MappingProviderStore.ProviderType.Filter:
mapping.AddFilter(((IFilterMappingProvider) x).GetFilterMapping());
break;
case MappingProviderStore.ProviderType.StoredProcedure:
mapping.AddStoredProcedure(((IStoredProcedureMappingProvider) x).GetStoredProcedureMapping());
break;
case MappingProviderStore.ProviderType.Join:
mapping.AddJoin(((IJoinMappingProvider) x).GetJoinMapping());
break;
case MappingProviderStore.ProviderType.Identity:
mapping.Set(y => y.Id, Layer.Defaults, ((IIdentityMappingProvider) x).GetIdentityMapping());
break;
case MappingProviderStore.ProviderType.CompositeId:
mapping.Set(y => y.Id, Layer.Defaults, ((ICompositeIdMappingProvider) x).GetCompositeIdMapping());
break;
case MappingProviderStore.ProviderType.NaturalId:
mapping.Set(y => y.NaturalId, Layer.Defaults, ((INaturalIdMappingProvider) x).GetNaturalIdMapping());
break;
case MappingProviderStore.ProviderType.Version:
mapping.Set(y => y.Version, Layer.Defaults, ((IVersionMappingProvider) x).GetVersionMapping());
break;
case MappingProviderStore.ProviderType.Discriminator:
mapping.Set(y => y.Discriminator, Layer.Defaults, ((IDiscriminatorMappingProvider) x).GetDiscriminatorMapping());
break;
case MappingProviderStore.ProviderType.Tupilizer:
mapping.Set(y => y.Tuplizer, Layer.Defaults, (TuplizerMapping)x);
break;
default:
throw new Exception("Internal Error");
}
}

if (Cache.IsDirty)
mapping.Set(x => x.Cache, Layer.Defaults, ((ICacheMappingProvider)Cache).GetCacheMapping());

if (providers.Id != null)
mapping.Set(x => x.Id, Layer.Defaults, providers.Id.GetIdentityMapping());

if (providers.CompositeId != null)
mapping.Set(x => x.Id, Layer.Defaults, providers.CompositeId.GetCompositeIdMapping());

if (providers.NaturalId != null)
mapping.Set(x => x.NaturalId, Layer.Defaults, providers.NaturalId.GetNaturalIdMapping());

mapping.Set(x => x.TableName, Layer.Defaults, GetDefaultTableName());

foreach (var filter in providers.Filters)
mapping.AddFilter(filter.GetFilterMapping());

foreach (var storedProcedure in providers.StoredProcedures)
mapping.AddStoredProcedure(storedProcedure.GetStoredProcedureMapping());

mapping.Set(x => x.Tuplizer, Layer.Defaults, providers.TuplizerMapping);

return mapping;
Expand Down
209 changes: 191 additions & 18 deletions src/FluentNHibernate/Mapping/MappingProviderStore.cs
Original file line number Diff line number Diff line change
@@ -1,42 +1,215 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.Linq;
using FluentNHibernate.Mapping.Providers;
using FluentNHibernate.MappingModel;
using FluentNHibernate.Utils;

namespace FluentNHibernate.Mapping
{
public class MappingProviderStore
{
public enum ProviderType {
Property,
Component,
OneToOne,
Subclass,
Collection,
ManyToOne,
Any,
Filter,
StoredProcedure,
Join,
Identity,
CompositeId,
NaturalId,
Version,
Discriminator,
Tupilizer
}

public IList<IPropertyMappingProvider> Properties { get; set; }
public IList<IComponentMappingProvider> Components { get; set; }
public IList<IOneToOneMappingProvider> OneToOnes { get; set; }
public Dictionary<Type, ISubclassMappingProvider> Subclasses { get; set; }
public IDictionary<Type, ISubclassMappingProvider> Subclasses { get; set; }
public IList<ICollectionMappingProvider> Collections { get; set; }
public IList<IManyToOneMappingProvider> References { get; set; }
public IList<IAnyMappingProvider> Anys { get; set; }
public IList<IFilterMappingProvider> Filters { get; set; }
public IList<IStoredProcedureMappingProvider> StoredProcedures { get; set; }
public IList<IJoinMappingProvider> Joins { get; set; }
private IIdentityMappingProvider _id;
private ICompositeIdMappingProvider _compositeId;
private INaturalIdMappingProvider _naturalId;
private IVersionMappingProvider _version;
private IDiscriminatorMappingProvider _discriminator;
private TuplizerMapping _tupilizerMapping;
private readonly IList<Tuple<ProviderType, object>> _orderedProviders;


public IIdentityMappingProvider Id {
get => _id;
set {
ReplaceOrAddProvider(ProviderType.Identity, _id, value);
_id = value;
}
}

public ICompositeIdMappingProvider CompositeId {
get => _compositeId;
set {
ReplaceOrAddProvider(ProviderType.CompositeId, _compositeId, value);
_compositeId = value;
}
}

public INaturalIdMappingProvider NaturalId {
get => _naturalId;
set {
ReplaceOrAddProvider(ProviderType.NaturalId, _naturalId, value);
_naturalId = value;
}
}

public IVersionMappingProvider Version {
get => _version;
set {
ReplaceOrAddProvider(ProviderType.Version, _version, value);
_version = value;
}
}

public IDiscriminatorMappingProvider Discriminator {
get => _discriminator;
set {
ReplaceOrAddProvider(ProviderType.Discriminator, _discriminator, value);
_discriminator = value;
}
}

public IIdentityMappingProvider Id { get; set; }
public ICompositeIdMappingProvider CompositeId { get; set; }
public INaturalIdMappingProvider NaturalId { get; set; }
public IVersionMappingProvider Version { get; set; }
public IDiscriminatorMappingProvider Discriminator { get; set; }
public TuplizerMapping TuplizerMapping { get; set; }
public TuplizerMapping TuplizerMapping {
get => _tupilizerMapping;
set {
ReplaceOrAddProvider(ProviderType.Tupilizer, _tupilizerMapping, value);
_tupilizerMapping = value;
}
}

public MappingProviderStore()
{
Properties = new List<IPropertyMappingProvider>();
Components = new List<IComponentMappingProvider>();
OneToOnes = new List<IOneToOneMappingProvider>();
Subclasses = new Dictionary<Type, ISubclassMappingProvider>();
Collections = new List<ICollectionMappingProvider>();
References = new List<IManyToOneMappingProvider>();
Anys = new List<IAnyMappingProvider>();
Filters = new List<IFilterMappingProvider>();
StoredProcedures = new List<IStoredProcedureMappingProvider>();
Joins = new List<IJoinMappingProvider>();
{
Properties = NewObservedList<IPropertyMappingProvider>();
Components = NewObservedList<IComponentMappingProvider>();
OneToOnes = NewObservedList<IOneToOneMappingProvider>();
Subclasses = NewObservedDictionary<Type, ISubclassMappingProvider>();
Collections = NewObservedList<ICollectionMappingProvider>();
References = NewObservedList<IManyToOneMappingProvider>();
Anys = NewObservedList<IAnyMappingProvider>();
Filters = NewObservedList<IFilterMappingProvider>();
StoredProcedures = NewObservedList<IStoredProcedureMappingProvider>();
Joins = NewObservedList<IJoinMappingProvider>();
_orderedProviders = new List<Tuple<ProviderType, object>>();
}

public IEnumerable<Tuple<ProviderType, object>> OrderedProviders {
get { return _orderedProviders.Select(x => x); }
}

private IList<T> NewObservedList<T>() {

ProviderType TypeSelector(object mappingStoreCollection)
{
if (ReferenceEquals(mappingStoreCollection, Properties)) {
return ProviderType.Property;
} else if (ReferenceEquals(mappingStoreCollection, Components)) {
return ProviderType.Component;
} else if (ReferenceEquals(mappingStoreCollection, OneToOnes)) {
return ProviderType.OneToOne;
} else if (ReferenceEquals(mappingStoreCollection, Collections)) {
return ProviderType.Collection;
} else if (ReferenceEquals(mappingStoreCollection, References)) {
return ProviderType.ManyToOne;
} else if (ReferenceEquals(mappingStoreCollection, Anys)) {
return ProviderType.Any;
} else if (ReferenceEquals(mappingStoreCollection, Filters)) {
return ProviderType.Filter;
} else if (ReferenceEquals(mappingStoreCollection, StoredProcedures)) {
return ProviderType.StoredProcedure;
} else if (ReferenceEquals(mappingStoreCollection, Joins)) {
return ProviderType.Join;
}
throw new Exception("Internal Error");
}

var observableList = new ObservableCollection<T>();
observableList.CollectionChanged += (sender, args) => {
var type = TypeSelector(sender);
switch (args.Action) {
case NotifyCollectionChangedAction.Add:
foreach (var newItem in args.NewItems)
_orderedProviders.Add(Tuple.Create(type, newItem));
break;
case NotifyCollectionChangedAction.Move:
throw new NotSupportedException();

case NotifyCollectionChangedAction.Remove:
foreach (var oldItem in args.OldItems)
_orderedProviders.Remove(Tuple.Create(type, oldItem));
break;
case NotifyCollectionChangedAction.Replace:
throw new NotSupportedException();
case NotifyCollectionChangedAction.Reset:
foreach (var oldItem in args.OldItems)
_orderedProviders.Remove(Tuple.Create(type, oldItem));
break;
}
};
return observableList;
}

private IDictionary<TKey, TVal> NewObservedDictionary<TKey, TVal>() {
var observedDictionary = new ObservableDictionary<TKey,TVal>();
observedDictionary.CollectionChanged += (sender, args) => {
switch (args.Action) {
case NotifyCollectionChangedAction.Add:
if (args.NewStartingIndex < ((IDictionary<TKey, TVal>)sender).Count) {
//Inserting
for (var i = 0; i < args.NewItems.Count; i++) {
var newValue = (KeyValuePair<TKey, TVal>)args.NewItems[i];
_orderedProviders.Insert(args.NewStartingIndex + i, Tuple.Create(ProviderType.Subclass, (object)newValue.Value));
}
} else {
//Appending
foreach (KeyValuePair<TKey, TVal> newItem in args.NewItems) {
_orderedProviders.Add(Tuple.Create(ProviderType.Subclass, (object)newItem.Value));
}
}
break;
case NotifyCollectionChangedAction.Move:
throw new NotSupportedException();
case NotifyCollectionChangedAction.Remove:
foreach (KeyValuePair<TKey, TVal> oldItem in args.OldItems)
_orderedProviders.Remove(Tuple.Create(ProviderType.Subclass, (object)oldItem.Value));
break;
case NotifyCollectionChangedAction.Replace:
throw new NotSupportedException();
case NotifyCollectionChangedAction.Reset:
foreach (KeyValuePair<TKey, TVal> oldItem in args.OldItems)
_orderedProviders.Remove(Tuple.Create(ProviderType.Subclass, (object)oldItem.Value));
break;
}
};
return observedDictionary;
}

private void ReplaceOrAddProvider(ProviderType type, object oldObj, object newObj) {
var index = _orderedProviders.IndexOf(Tuple.Create(type, oldObj));
var newObjTuple = Tuple.Create(type, newObj);
if (index > 0)
_orderedProviders[index] = newObjTuple;
else
_orderedProviders.Add(newObjTuple);
}
}
}
Loading