diff --git a/src/Orchard/Data/DefaultSessionConfigurationEvents.cs b/src/Orchard/Data/DefaultSessionConfigurationEvents.cs new file mode 100644 index 000000000..55ecf72d3 --- /dev/null +++ b/src/Orchard/Data/DefaultSessionConfigurationEvents.cs @@ -0,0 +1,22 @@ +using FluentNHibernate.Automapping; +using FluentNHibernate.Cfg; + +namespace Orchard.Data { + /// + /// Base class for session configuration + /// + public class DefaultSessionConfigurationEvents : SessionConfigurationEventsWithParameters { + /// + /// Called when an empty fluent configuration object has been created, + /// before applying any default Orchard config settings (alterations, conventions etc.). + /// + /// Empty fluent NH configuration object. + /// Default persistence model that is about to be used. + public override void Created(FluentConfiguration cfg, AutoPersistenceModel defaultModel) { + defaultModel.OverrideAll(map => { + map.IgnoreProperties(x => x.MemberInfo.IsDefined(typeof(DoNotMapAttribute), false)); + }); + } + } +} + diff --git a/src/Orchard/Data/DoNotMapAttribute.cs b/src/Orchard/Data/DoNotMapAttribute.cs new file mode 100644 index 000000000..b625d4029 --- /dev/null +++ b/src/Orchard/Data/DoNotMapAttribute.cs @@ -0,0 +1,19 @@ +using System; + +namespace Orchard.Data { + /// + /// Mark a property to be excluded from NHibernate mapping + /// + public class DoNotMapAttribute : Attribute { + } +} + +//usage: +// +//public class PersonRecord { +// public virtual int Id { get; set; } +// public virtual string FirstName { get; set; } +// public virtual string LastName { get; set; } +// [DoNotMap] +// public virtual string FullName { get {return Fullname+", "+LastName;} } +//} \ No newline at end of file diff --git a/src/Orchard/Data/ISessionConfigurationEventsWithParameters.cs b/src/Orchard/Data/ISessionConfigurationEventsWithParameters.cs new file mode 100644 index 000000000..e7042ee91 --- /dev/null +++ b/src/Orchard/Data/ISessionConfigurationEventsWithParameters.cs @@ -0,0 +1,86 @@ +using FluentNHibernate.Automapping; +using FluentNHibernate.Cfg; +using NHibernate.Cfg; +using Orchard.Utility; +using Orchard.Data.Providers; + +namespace Orchard.Data { + /// + /// Add ability for the configuration event handler be aware of parameters + /// + /// + public interface ISessionConfigurationEventsWithParameters : ISessionConfigurationEvents { + SessionFactoryParameters Parameters { set; get; } + } +} + +// usage sample +//using System; +//using System.Collections.Generic; +//using System.Linq; +//using FluentNHibernate.Automapping; +//using FluentNHibernate.Cfg; +//using FluentNHibernate.Conventions; +//using FluentNHibernate.Conventions.Instances; +//using NHibernate.Cfg; +//using Orchard.Data; +//using Orchard.Environment.ShellBuilders.Models; +//using Orchard.Utility; + +//namespace usage_example { + +// public class PersistenceConfiguration : ISessionConfigurationEventsWithParameters { +// Orchard.Data.Providers.SessionFactoryParameters _parameters; + +// public PersistenceConfiguration() { +// } + +// public void SetParameters(Orchard.Data.Providers.SessionFactoryParameters parameters) { +// _parameters = parameters; +// } + +// public void Created(FluentConfiguration cfg, AutoPersistenceModel defaultModel) { +// Dictionary descriptors = _parameters.RecordDescriptors.ToDictionary(d => d.Type); +// defaultModel.Conventions.Add(new IbnJoinedSubclassConvention(descriptors)); +// defaultModel.OverrideAll(map => { +// map.IgnoreProperties(x => x.MemberInfo.IsDefined(typeof(DoNotMapAttribute), false)); +// }); +// } + +// public void Prepared(FluentConfiguration cfg) { +// } + +// public void Building(Configuration cfg) { +// } + +// public void Finished(Configuration cfg) { +// } + +// public void ComputingHash(Hash hash) { +// } +// } + + +// public class IbnJoinedSubclassConvention : IJoinedSubclassConvention { +// private readonly Dictionary _descriptors; + +// public IbnJoinedSubclassConvention(Dictionary descriptors) { +// _descriptors = descriptors; +// } + +// public void Apply(IJoinedSubclassInstance instance) { +// if (instance.EntityType.FullName.StartsWith("Ibn")) { +// instance.Key.Column("Id"); +// RecordBlueprint desc; +// if (_descriptors.TryGetValue(instance.EntityType, out desc)) { +// instance.Table(desc.TableName); +// } +// } +// } +// } + + +// public class DoNotMapAttribute : Attribute { +// } + +//} \ No newline at end of file diff --git a/src/Orchard/Data/Providers/AbstractDataServicesProvider.cs b/src/Orchard/Data/Providers/AbstractDataServicesProvider.cs index 21aefab47..c1a50bc44 100644 --- a/src/Orchard/Data/Providers/AbstractDataServicesProvider.cs +++ b/src/Orchard/Data/Providers/AbstractDataServicesProvider.cs @@ -38,18 +38,15 @@ namespace Orchard.Data.Providers { var config = Fluently.Configure(); - // not working for me.. (BN) - //parameters.Configurers.OfType() - // .Invoke(c => c.Parameters=parameters, Logger); - - foreach (var c in parameters.Configurers.OfType()) + foreach (var c in parameters.Configurers.OfType()) { c.Parameters = parameters; + } parameters.Configurers.Invoke(c => c.Created(config, persistenceModel), Logger); config = config.Database(database) .Mappings(m => m.AutoMappings.Add(persistenceModel)) - .ExposeConfiguration(cfg => { + .ExposeConfiguration(cfg => { cfg .SetProperty(NHibernate.Cfg.Environment.FormatSql, Boolean.FalseString) .SetProperty(NHibernate.Cfg.Environment.GenerateStatistics, Boolean.FalseString) @@ -65,16 +62,16 @@ namespace Orchard.Data.Providers { .SetProperty(NHibernate.Cfg.Environment.BatchSize, "256") ; - cfg.EventListeners.LoadEventListeners = new ILoadEventListener[] {new OrchardLoadEventListener()}; + cfg.EventListeners.LoadEventListeners = new ILoadEventListener[] { new OrchardLoadEventListener() }; cfg.EventListeners.PostLoadEventListeners = new IPostLoadEventListener[0]; cfg.EventListeners.PreLoadEventListeners = new IPreLoadEventListener[0]; - + // don't enable PrepareSql by default as it breaks on SqlCe // this can be done per driver by overriding AlterConfiguration AlterConfiguration(cfg); parameters.Configurers.Invoke(c => c.Building(cfg), Logger); - + }) ; @@ -84,11 +81,11 @@ namespace Orchard.Data.Providers { } protected virtual void AlterConfiguration(Configuration config) { - + } public static AutoPersistenceModel CreatePersistenceModel(ICollection recordDescriptors) { - if(recordDescriptors == null) { + if (recordDescriptors == null) { throw new ArgumentNullException("recordDescriptors"); } @@ -116,7 +113,7 @@ namespace Orchard.Data.Providers { public TypeSource(IEnumerable recordDescriptors) { _recordDescriptors = recordDescriptors; } public IEnumerable GetTypes() { return _recordDescriptors.Select(descriptor => descriptor.Type); } - + public void LogSource(IDiagnosticLogger logger) { throw new NotImplementedException(); } @@ -135,8 +132,7 @@ namespace Orchard.Data.Providers { if (@event.InstanceToLoad != null) { entityPersister = source.GetEntityPersister(null, @event.InstanceToLoad); @event.EntityClassName = @event.InstanceToLoad.GetType().FullName; - } - else + } else entityPersister = source.Factory.GetEntityPersister(@event.EntityClassName); if (entityPersister == null) throw new HibernateException("Unable to locate persister: " + @event.EntityClassName); @@ -161,11 +157,9 @@ namespace Orchard.Data.Providers { if (loadType.IsNakedEntityReturned) { @event.Result = Load(@event, entityPersister, keyToLoad, loadType); - } - else if (@event.LockMode == LockMode.None) { + } else if (@event.LockMode == LockMode.None) { @event.Result = ProxyOrLoad(@event, entityPersister, keyToLoad, loadType); - } - else { + } else { @event.Result = LockAndLoad(@event, entityPersister, keyToLoad, loadType, source); } } diff --git a/src/Orchard/Data/SessionConfigurationEventsWithParameters.cs b/src/Orchard/Data/SessionConfigurationEventsWithParameters.cs new file mode 100644 index 000000000..15707f120 --- /dev/null +++ b/src/Orchard/Data/SessionConfigurationEventsWithParameters.cs @@ -0,0 +1,76 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using FluentNHibernate.Automapping; +using FluentNHibernate.Cfg; +using NHibernate.Cfg; +using Orchard.Data.Providers; +using Orchard.Environment.ShellBuilders.Models; +using Orchard.Utility; + +namespace Orchard.Data +{ + /// + /// Base class for session configuration + /// + public abstract class SessionConfigurationEventsWithParameters : ISessionConfigurationEventsWithParameters + { + /// + /// The parameters are set before any of the functions are called. + /// + public SessionFactoryParameters Parameters { set; get; } + + /// + /// Returns the BlueprintDescriptors - translating from type to DB Table names + /// + public Dictionary BlueprintDescriptors { + get { + if (_descriptors == null) + _descriptors = Parameters.RecordDescriptors.ToDictionary(d => d.Type); + return _descriptors; + } + } + protected Dictionary _descriptors = null; + + /// + /// Called when an empty fluent configuration object has been created, + /// before applying any default Orchard config settings (alterations, conventions etc.). + /// + /// Empty fluent NH configuration object. + /// Default persistence model that is about to be used. + public virtual void Created(FluentConfiguration cfg, AutoPersistenceModel defaultModel) { } + + /// + /// Called when fluent configuration has been prepared but not yet built. + /// + /// Prepared fluent NH configuration object. + public virtual void Prepared(FluentConfiguration cfg) { } + + /// + /// Called when raw NHibernate configuration is being built, after applying all customizations. + /// Allows applying final alterations to the raw NH configuration. + /// + /// Raw NH configuration object being processed. + public virtual void Building(Configuration cfg) { } + + /// + /// Called when NHibernate configuration has been built or read from cache storage (mappings.bin file by default). + /// + /// Final, raw NH configuration object. + public virtual void Finished(Configuration cfg) { } + + /// + /// Called when configuration hash is being computed. If hash changes, configuration will be rebuilt and stored in mappings.bin. + /// This method allows to alter the default hash to take into account custom configuration changes. + /// + /// + /// It's a developer responsibility to make sure hash is correctly updated when config needs to be rebuilt. + /// Otherwise the cached configuration (mappings.bin file) will be used as long as default Orchard configuration + /// is unchanged or until the file is manually removed. + /// + /// Current hash object + public virtual void ComputingHash(Hash hash) { } + } + +} + diff --git a/src/Orchard/Orchard.Framework.csproj b/src/Orchard/Orchard.Framework.csproj index c4ae62f5e..fb6475945 100644 --- a/src/Orchard/Orchard.Framework.csproj +++ b/src/Orchard/Orchard.Framework.csproj @@ -181,7 +181,7 @@ - +