Skip to content
This repository has been archived by the owner on Aug 16, 2018. It is now read-only.

Commit

Permalink
Add NHibernateSessionFactoryBuilder, see sharparchitecture#61
Browse files Browse the repository at this point in the history
  • Loading branch information
cd21h committed May 30, 2015
1 parent e982b69 commit e09d7b9
Show file tree
Hide file tree
Showing 10 changed files with 342 additions and 122 deletions.
14 changes: 14 additions & 0 deletions Samples/TardisBank/Solutions/Suteki.TardisBank.sln
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,10 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Build", "Build", "{F8324423
..\Build\BuildAndPackage.cmd = ..\Build\BuildAndPackage.cmd
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SharpArch.Wcf", "..\..\..\Solutions\SharpArch.Wcf\SharpArch.Wcf.csproj", "{F7F5E614-3B4E-43EC-8F8A-CB46B89A3827}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SharpArch.WcfClient.Castle", "..\..\..\Solutions\SharpArch.WcfClient.Castle\SharpArch.WcfClient.Castle.csproj", "{A3B21E07-F25F-46D3-B4DE-EA29A0A4A831}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -118,6 +122,14 @@ Global
{EB01CD4D-CFB9-4924-8388-078D59543D58}.Debug|Any CPU.Build.0 = Debug|Any CPU
{EB01CD4D-CFB9-4924-8388-078D59543D58}.Release|Any CPU.ActiveCfg = Release|Any CPU
{EB01CD4D-CFB9-4924-8388-078D59543D58}.Release|Any CPU.Build.0 = Release|Any CPU
{F7F5E614-3B4E-43EC-8F8A-CB46B89A3827}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F7F5E614-3B4E-43EC-8F8A-CB46B89A3827}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F7F5E614-3B4E-43EC-8F8A-CB46B89A3827}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F7F5E614-3B4E-43EC-8F8A-CB46B89A3827}.Release|Any CPU.Build.0 = Release|Any CPU
{A3B21E07-F25F-46D3-B4DE-EA29A0A4A831}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A3B21E07-F25F-46D3-B4DE-EA29A0A4A831}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A3B21E07-F25F-46D3-B4DE-EA29A0A4A831}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A3B21E07-F25F-46D3-B4DE-EA29A0A4A831}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand All @@ -136,5 +148,7 @@ Global
{5C2EA19A-E547-4E55-B36E-B25CA9EFEF21} = {8AB1F99F-E7F1-403D-BEFB-B0157C5E81A0}
{D6DDE603-4678-44B9-A2D1-101BF5D12AD7} = {8AB1F99F-E7F1-403D-BEFB-B0157C5E81A0}
{EB01CD4D-CFB9-4924-8388-078D59543D58} = {8AB1F99F-E7F1-403D-BEFB-B0157C5E81A0}
{F7F5E614-3B4E-43EC-8F8A-CB46B89A3827} = {8AB1F99F-E7F1-403D-BEFB-B0157C5E81A0}
{A3B21E07-F25F-46D3-B4DE-EA29A0A4A831} = {8AB1F99F-E7F1-403D-BEFB-B0157C5E81A0}
EndGlobalSection
EndGlobal
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
namespace SharpArch.NHibernate
{
using System.Collections.Generic;
using global::NHibernate.Cfg;

/// <summary>
Expand All @@ -15,7 +16,7 @@ public interface INHibernateConfigurationCache
/// cached <see cref = "Configuration" /> is out of date or not.</param>
/// <param name="mappingAssemblies">List of assemblies containing HBM files.</param>
/// <returns>If an up to date cached object is available, a <see cref = "Configuration" /> object, otherwise null.</returns>
Configuration LoadConfiguration(string configKey, string configPath, string[] mappingAssemblies);
Configuration LoadConfiguration(string configKey, string configPath, IEnumerable<string> mappingAssemblies);

/// <summary>
/// Save the <see cref = "Configuration" /> object to a cache.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ public NHibernateConfigurationFileCache(string[] dependentFilePaths)
/// cached <see cref="Configuration"/> is out of date or not.</param>
/// <returns>If an up to date cached object is available, a <see cref="Configuration"/>
/// object, otherwise null.</returns>
public Configuration LoadConfiguration(string configKey, string configPath, string[] mappingAssemblies)
public Configuration LoadConfiguration(string configKey, string configPath, IEnumerable<string> mappingAssemblies)
{
string cachePath = CachedConfigPath(configKey);
AppendToDependentFilePaths(mappingAssemblies);
Expand Down
1 change: 1 addition & 0 deletions Solutions/SharpArch.NHibernate/NHibernateSession.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

using SharpArch.NHibernate.NHibernateValidator;

[Obsolete("Use NHibernateSessionFacgtoryBuilder")]
public static class NHibernateSession
{
/// <summary>
Expand Down
203 changes: 203 additions & 0 deletions Solutions/SharpArch.NHibernate/NHibernateSessionFactoryBuilder.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,203 @@
namespace SharpArch.NHibernate
{
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using Domain;
using global::FluentNHibernate.Automapping;
using global::FluentNHibernate.Cfg;
using global::FluentNHibernate.Cfg.Db;
using global::NHibernate;
using global::NHibernate.Cfg;
using NHibernateValidator;

/// <summary>
/// Creates NHibernate SessionFactory <see cref="ISessionFactory" />
/// </summary>
/// <remarks>
/// Transient object, session factory must be redistered as singletone in DI Container.
/// </remarks>
public class NHibernateSessionFactoryBuilder
{
/// <summary>
/// Default configuration file name.
/// </summary>
public const string DefaultNHibernateConfigFileName = "Hibernate.cfg.xml";

private INHibernateConfigurationCache configurationCache;
private readonly string configurationName = "Default";
private AutoPersistenceModel autoPersistenceModel;
private string configFile;
private readonly List<string> mappingAssemblies;
private IPersistenceConfigurer persistenceConfigurer;
private IDictionary<string, string> properties;
private bool useDataAnnotationValidators;

/// <summary>
/// Initializes a new instance of the <see cref="NHibernateSessionFactoryBuilder"/> class.
/// </summary>
public NHibernateSessionFactoryBuilder()
{
this.configurationCache = NullNHibernateConfigurationCache.Null;
this.mappingAssemblies = new List<string>();
}


/// <summary>
/// Creates the session factory.
/// </summary>
/// <returns> NHibernate session factory <see cref="ISessionFactory"/>.</returns>
public ISessionFactory CreateSessionFactory()
{
var configuration = BuildConfiguration();

return configuration.BuildSessionFactory();
}


public Configuration BuildConfiguration()
{
var configuration = configurationCache.LoadConfiguration(configurationName, configFile, mappingAssemblies);

if (configuration == null)
{
configuration = LoadExternalConfiguration();
configuration = ApplyCustomSettings(configuration);
configurationCache.SaveConfiguration(configurationName, configuration);
}
return configuration;
}

public NHibernateSessionFactoryBuilder UseConfigurationCache(INHibernateConfigurationCache configurationCache)
{
Check.Require(configurationCache != null, "Please provide configuration cache instance.");
this.configurationCache = configurationCache;
return this;
}

public NHibernateSessionFactoryBuilder UseMappingAssemblies(IEnumerable<string> mappingAssemblies)
{
Check.Require(mappingAssemblies != null, "Please specify mapping assemblies.");
this.mappingAssemblies.AddRange(mappingAssemblies);
return this;
}

public NHibernateSessionFactoryBuilder UseAutoPersitenceModel(AutoPersistenceModel autoPersistenceModel)
{
Check.Require(autoPersistenceModel != null);
this.autoPersistenceModel = autoPersistenceModel;
return this;
}

public NHibernateSessionFactoryBuilder UseProperties(IDictionary<string, string> properties)
{
Check.Require(properties != null);
this.properties = properties;

return this;
}


public NHibernateSessionFactoryBuilder UseDataAnnotationValidators(bool addDataAnnotatonValidators)
{
this.useDataAnnotationValidators = addDataAnnotatonValidators;
return this;
}

public NHibernateSessionFactoryBuilder UseConfigFile(string nhibernateConfigFile)
{
Check.Require(!string.IsNullOrEmpty(nhibernateConfigFile), "NHibernate config file must be specified");
configFile = nhibernateConfigFile;

return this;
}

public NHibernateSessionFactoryBuilder UsePersistenceConfigurer(IPersistenceConfigurer persistenceConfigurer)
{
Check.Require(persistenceConfigurer != null);
this.persistenceConfigurer = persistenceConfigurer;
return this;
}

private Configuration ApplyCustomSettings(Configuration cfg)
{
var fluentConfig = Fluently.Configure(cfg);
if (persistenceConfigurer != null)
{
fluentConfig.Database(persistenceConfigurer);
}

fluentConfig.Mappings(m =>
{
foreach (string mappingAssembly in this.mappingAssemblies)
{
Assembly assembly = Assembly.LoadFrom(MakeLoadReadyAssemblyName(mappingAssembly));
m.HbmMappings.AddFromAssembly(assembly);
m.FluentMappings.AddFromAssembly(assembly).Conventions.AddAssembly(assembly);
}
if (autoPersistenceModel != null)
{
m.AutoMappings.Add(autoPersistenceModel);
}
});

if (this.useDataAnnotationValidators)
{
fluentConfig.ExposeConfiguration(
e =>
{
e.EventListeners.PreInsertEventListeners = InsertFirst(e.EventListeners.PreInsertEventListeners,
new DataAnnotationsEventListener());
e.EventListeners.PreUpdateEventListeners = InsertFirst(e.EventListeners.PreUpdateEventListeners,
new DataAnnotationsEventListener());
});
}
return fluentConfig.BuildConfiguration();
}

/// <summary>
/// Loads configuration from properties dictionary and from external file if avaiable.
/// </summary>
/// <returns></returns>
private Configuration LoadExternalConfiguration()
{
var cfg = new Configuration();
if (properties != null && properties.Any())
{
cfg.AddProperties(properties);
}
if (!string.IsNullOrEmpty(configFile))
{
return cfg.Configure(configFile);
}
if (File.Exists(DefaultNHibernateConfigFileName))
{
return cfg.Configure();
}
return cfg;
}

private static T[] InsertFirst<T>(T[] array, T item)
{
if (array == null)
{
return new[] {item};
}

var items = new List<T> {item};
items.AddRange(array);
return items.ToArray();
}

private static string MakeLoadReadyAssemblyName(string assemblyName)
{
return (assemblyName.IndexOf(".dll", StringComparison.OrdinalIgnoreCase) == -1)
? assemblyName.Trim() + ".dll"
: assemblyName.Trim();
}
}
}
30 changes: 30 additions & 0 deletions Solutions/SharpArch.NHibernate/NullNHibernateConfigurationCache.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
namespace SharpArch.NHibernate
{
using System.Collections.Generic;
using global::NHibernate.Cfg;

/// <summary>
/// Null Object for configuration cache.
/// </summary>
class NullNHibernateConfigurationCache : INHibernateConfigurationCache
{
internal NullNHibernateConfigurationCache()
{
}

/// <summary>
/// Instance.
/// </summary>
public static readonly INHibernateConfigurationCache Null = new NullNHibernateConfigurationCache();

public Configuration LoadConfiguration(string configKey, string configPath, IEnumerable<string> mappingAssemblies)
{
return null;
}

public void SaveConfiguration(string configKey, Configuration config)
{

}
}
}
2 changes: 2 additions & 0 deletions Solutions/SharpArch.NHibernate/SharpArch.NHibernate.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,8 @@
</Compile>
<Compile Include="Contracts\Repositories\INHibernateRepository.cs" />
<Compile Include="Contracts\Repositories\INHibernateRepositoryWithTypeId.cs" />
<Compile Include="NHibernateSessionFactoryBuilder.cs" />
<Compile Include="NullNHibernateConfigurationCache.cs" />
<Compile Include="TransactionManager.cs" />
<Compile Include="DefaultSessionFactoryKeyProvider.cs" />
<Compile Include="EntityDuplicateChecker.cs" />
Expand Down
Loading

0 comments on commit e09d7b9

Please sign in to comment.