Skip to content

Instantly share code, notes, and snippets.

@shadowman
Created April 15, 2012 13:51
NHibernate interceptor that reads localized database content
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Localization.NHibernate
{
public class LocalizationEntryId
{
public virtual string Culture { get; set; }
public virtual string Type { get; set; }
public virtual string Property { get; set; }
public virtual string EntityId { get; set; }
public override bool Equals(object obj)
{
if (obj != null)
{
LocalizationEntryId other = obj as LocalizationEntryId;
if (other != null)
{
return this.Type == other.Type &&
this.Property == other.Property &&
this.EntityId == other.EntityId &&
this.Culture == other.Culture;
}
}
return false;
}
public override int GetHashCode()
{
return base.GetHashCode();
}
}
public class LocalizationEntry
{
public virtual LocalizationEntryId Id { get; set; }
public virtual string Message { get; set; }
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Localization.NHibernate;
using FluentNHibernate.Mapping;
namespace Localization.Mappings
{
public class LocalizationEntryMapping: ClassMap<LocalizationEntry>
{
public LocalizationEntryMapping()
{
Cache.ReadWrite();
CompositeId()
.ComponentCompositeIdentifier(x => x.Id)
.KeyProperty(x => x.Id.Culture)
.KeyProperty(x => x.Id.EntityId)
.KeyProperty(x => x.Id.Property)
.KeyProperty(x => x.Id.Type);
Map(x => x.Message);
}
}
}
using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using NHibernate;
using FluentNHibernate.Cfg;
using FluentNHibernate.Cfg.Db;
using NHibernate.Cfg;
using NHibernate.Tool.hbm2ddl;
using System.IO;
using System.Threading;
using System.Globalization;
using Localization.NHibernate;
namespace Localization
{
[TestClass]
public class LocalizationIntegrationTests
{
private static CultureInfo DEFAULT_CULTURE = new CultureInfo("en-US");
private static CultureInfo SPANISH_CULTURE = new CultureInfo("es-ES");
private static CultureInfo NOT_FOUND_CULTURE = new CultureInfo("fr-FR");
private static string LOCALIZED_PROPERTY_NAME = "Title";
[ClassInitialize]
public static void StaticTestsInitialization(TestContext context)
{
InitializeDatabaseProvider();
PopulateDatabaseWithReadOnlyTestData();
}
private static void InitializeDatabaseProvider()
{
Factory = Fluently.Configure()
.Database(
SQLiteConfiguration.Standard
.UsingFile("sample.db")
.ShowSql()
)
.Mappings(x => x.FluentMappings.AddFromAssemblyOf<LocalizationIntegrationTests>())
.ExposeConfiguration(BuildDatabase)
.Cache(
x => x.UseSecondLevelCache()
.UseQueryCache()
.ProviderClass<global::NHibernate.Cache.HashtableCacheProvider>())
.BuildSessionFactory();
}
private static void PopulateDatabaseWithReadOnlyTestData()
{
using (ISession session = Factory.OpenSession())
{
Article article = new Article() {
Id = ArticlesMotherObject.LOCALIZED_ARTICLE_ID,
Title = ArticlesMotherObject.DEFAULT_TITLE
};
session.Save(article);
LocalizationEntry entry = new LocalizationEntry()
{
Id = new LocalizationEntryId()
{
EntityId = ArticlesMotherObject.LOCALIZED_ARTICLE_ID.ToString(),
Culture = SPANISH_CULTURE.ThreeLetterISOLanguageName,
Property = LOCALIZED_PROPERTY_NAME,
Type = typeof(Article).ToString()
},
Message = ArticlesMotherObject.SPANISH_TITLE
};
session.Save(entry);
session.Flush();
}
}
public static void BuildDatabase(Configuration configuration)
{
configuration.SetProperty("current_session_context_class", "thread_static");
if (File.Exists("sample.db"))
{
File.Delete("sample.db");
}
new SchemaExport(configuration).Create(true, true);
}
[TestInitialize]
public void TestInitialization()
{
}
[TestMethod]
public void ArticleCanBeLoadedUsingNHibernateAndSQLLiteDatabase()
{
using (ISession session = Factory.OpenSession())
{
Article article = session.Get<Article>(ArticlesMotherObject.LOCALIZED_ARTICLE_ID);
Assert.IsNotNull(article);
}
}
[TestMethod]
public void LocalizationEntryCanBeLoadedUsingNHibernateAndSQLLiteDatabase()
{
using (ISession session = Factory.OpenSession())
{
LocalizationEntry entry = session.Get<LocalizationEntry>(
new LocalizationEntryId() {
Type = typeof(Article).ToString(),
Culture = SPANISH_CULTURE.ThreeLetterISOLanguageName,
EntityId = ArticlesMotherObject.LOCALIZED_ARTICLE_ID.ToString(),
Property = LOCALIZED_PROPERTY_NAME
}
);
Assert.IsNotNull(entry);
}
}
[TestMethod]
public void ArticleTitleCanBeLoadedUsingNHibernateAndSQLLiteDatabase()
{
using (ISession session = Factory.OpenSession())
{
Article article = session.Get<Article>(ArticlesMotherObject.LOCALIZED_ARTICLE_ID);
Assert.AreEqual(ArticlesMotherObject.DEFAULT_TITLE, article.Title);
}
}
[TestMethod]
public void EnlgishVersionOfTheArticlesTitleWillBeLoadedUsingProvidedCultureIfAvailable()
{
using (ISession session = BuildLocalizedSession(DEFAULT_CULTURE))
{
Article article = session.Get<Article>(ArticlesMotherObject.LOCALIZED_ARTICLE_ID);
Assert.AreEqual(ArticlesMotherObject.DEFAULT_TITLE, article.Title);
}
}
[TestMethod]
public void SpanishVersionOfTheArticlesTitleWillBeLoadedUsingProvidedCultureIfAvailable()
{
using (ISession session = BuildLocalizedSession(SPANISH_CULTURE))
{
Article article = session.Get<Article>(ArticlesMotherObject.LOCALIZED_ARTICLE_ID);
Assert.AreEqual(ArticlesMotherObject.SPANISH_TITLE, article.Title);
}
}
[TestMethod]
public void DefaultVersionOfTheArticlesTitleWillBeLoadedIfProvidedCultureIsNotAvailable()
{
using (ISession session = BuildLocalizedSession(NOT_FOUND_CULTURE))
{
Article article = session.Get<Article>(ArticlesMotherObject.LOCALIZED_ARTICLE_ID);
Assert.AreEqual(ArticlesMotherObject.DEFAULT_TITLE, article.Title);
}
}
private static ISession BuildLocalizedSession(CultureInfo culture)
{
return Factory.OpenSession(new LocalizationInterceptor(culture, Factory));
}
public static ISessionFactory Factory { get; set; }
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NHibernate;
using NHibernate.Linq;
using System.Globalization;
using System.Threading;
namespace Localization.NHibernate
{
public class LocalizationInterceptor: EmptyInterceptor
{
public LocalizationInterceptor(ISessionFactory factory)
:this(Thread.CurrentThread.CurrentCulture, factory)
{
}
public LocalizationInterceptor(CultureInfo culture, ISessionFactory factory)
{
this.Culture = culture;
this.Factory = factory;
}
public override bool OnLoad(object entity, object id, object[] state, string[] propertyNames, global::NHibernate.Type.IType[] types)
{
using (ISession session = GetOrCreateSession())
{
for (int i = 0; i < propertyNames.Length; i++)
{
var message = session.Get<LocalizationEntry>(
new LocalizationEntryId
{
Culture = this.Culture.ThreeLetterISOLanguageName,
EntityId = id.ToString(),
Property = propertyNames[i],
Type = entity.GetType().FullName
}
);
if (message != null)
{
state[i] = message.Message;
}
}
}
return base.OnLoad(entity, id, state, propertyNames, types);
}
private ISession GetOrCreateSession()
{
ISession session = null;
try
{
session = Factory.GetCurrentSession();
}
catch (HibernateException)
{
session = Factory.OpenSession();
}
return session;
}
public CultureInfo Culture { get; set; }
public ISessionFactory Factory { get; set; }
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment