Create Multi-Language domain model (dynamic resource) with Nhibernate and database ?



1. Create a Culture Filter on one nhibernate mapping file :

 <?xml version="1.0" encoding="utf-8" ?>  
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" ...>
<class ...>
...
</class>
<filter-def name="CultureFilter">
<filter-param name="CultureCode" type="System.String" />
</filter-def>
</hibernate-mapping>


2. Declare the following tag of culture code in the mapping files related to the language table :

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping ...>
<class name="ProductTypeCulture" table="Product_Type_Culture" mutable="false">
<id name="ID" column="ProductTypeId" type="Int64" unsaved-value="0" >
<generator class="native" />
</id>
<property name="Label" column="Label" type="String" not-null="true"/>
<property name="CultureCode" column="CultureCode" type="String" not-null="true"/>
<filter name="CultureFilter" condition=":CultureCode = CultureCode"/>
</class>
</hibernate-mapping>



3. In the application_beginrequest, you should enable filter on the nhibernate session :

CultureCode = CultureInfo.CurrentCulture.TwoLetterISOLanguageName;
public string CultureCode
{
get { return CultureInfo.CurrentCulture.TwoLetterISOLanguageName; }
set
{
nhSession.EnableFilter(“CultureFilter”).SetParameter(“CultureCode”,value)
.Validate();
}
}



4. Now, the entity ProductTypeCulture should inherit the following class :

public class EntityCulture : Entity<EntityCulture>, ICloneable, IEntityCulture
{
#region Constructors
public EntityCulture() {}

public EntityCulture(string label)
{
_label = label;
}
#endregion

#region Properties
private string _label;
public virtual string CultureCode { get; set; }
public virtual string Label
{
get { return _label; }
set { _label = value; }
}
#endregion

#region ICloneable Members
public virtual object Clone()
{
var cloned = new EntityCulture {Label = Label};
return cloned;
}
#endregion

#region override
private int? _oldHashCode;
public override bool IsTransient()
{
return ID.Equals(0) || string.IsNullOrEmpty(CultureCode);
}
public virtual bool Equals(EntityCulture other)
{
if (ReferenceEquals(this, other))
return true;

if (other == null || !GetType().Equals(other.GetType()))
return false;

if (!IsTransient() && !other.IsTransient() && ID.Equals(other.ID) && CultureCode.Equals(other.CultureCode))
return true;

return IsTransient() && other.IsTransient();
}

public override bool Equals(object obj)
{
var compareTo = obj as EntityCulture;

return Equals(compareTo);
}

public override int GetHashCode()
{
if (_oldHashCode.HasValue)
return _oldHashCode.Value;

if (IsTransient())
{
_oldHashCode = base.GetHashCode();
return _oldHashCode.Value;
}

return ID.GetHashCode() + CultureCode.GetHashCode();
}

public override string ToString()
{
return GetType().FullName + "#" + ID + "-" + CultureCode;
}
#endregion
}
public interface IEntityCulture
{
string Label { get; set; }
object Clone();
}



5. Finally, the entity ProductType should inherit the following class :



public class EntityMultiLanguage<T, TCulture> : Entity<T>, IEntityMultiLanguage<TCulture> where T : class where TCulture : class, IEntityCulture
{
private IDictionary<string, TCulture> _resources;

#region IEntityMultiLanguage<TCulture> Members
public virtual string Label
{
get
{
TCulture res = GetResource();
return res != null ? res.Label : null;
}
set
{
GetOrCreateResource().Label = value;
}
}

public virtual IDictionary<string, TCulture> Resources
{
get { return _resources ?? new Dictionary<string, TCulture>(); }
set { _resources = value; }
}
#endregion

protected virtual TCulture GetDefaultResource()
{
return Resources.ContainsKey(CultureFilter.DefaultCulture.TwoLetterISOLanguageName)
? Resources[CultureFilter.DefaultCulture.TwoLetterISOLanguageName]
: null;
}

protected virtual TCulture GetOrCreateResource()
{
if (Resources.ContainsKey(CultureFilter.CultureCode))
return Resources[CultureFilter.CultureCode];

var newResource = GetResource().Clone() as TCulture;
Resources.Add(CultureFilter.CultureCode, newResource);
return newResource;
}
protected virtual TCulture GetResource()
{
return Resources.ContainsKey(CultureFilter.CultureCode)
? Resources[CultureFilter.CultureCode]
: GetDefaultResource();
}
}

No comments:

Post a Comment