Blog sur les technos .net
Puisque ces mystères me dépassent, feignons d'en être l'organisateur.

Faciliter vous les templates ( ex mail en .net ) | make mail template more easily

By TheGrandBlack

Qui ne s'est pas retrouvé à gérer des templates de texte dans applications.
( mail template , texte à l'ecran etc ... ).

L'idée c'est d'avoir la possibilité d'entreposer dans un référentiel tous les modèles et ensuite faire du remplacement avec les champs d'une base de données voir un classe.

un petit regard sur ce qui existe dans le frameWork .net : il existe bien la méthode "format" de la classe string "string.format", mais malheureusement cette méthode attend des indices.

Ce qui peut être tres lourd à gérer lors des modifications, évolutions et meme dans le travail courant car imaginez vous expliquer à un fonctionnel que dans son outils de back-office les modèles de mail utilisent des indices et que
{0} correspond au nom de la personne
{1} Prenom de la personne
{2} Civilité
etc ...

Non cela ne passera pas,

Donc l'idee c'est d'avoir une méthode tout comme "string.format" mais qui permettrait d'utiliser les noms plutot que des indices.

Pour faire cela on va utiliser la reflexion

L'idee c'est de récupérer le texte de template , d'avoir une classe

Exemple d'utilisation :




private void button1_Click(object sender, EventArgs e)
{
PersonEntity v_pers = new PersonEntity("Daniel", "GAVARIN", 18);
string v_mask = "Bonjour {Nom}, {Prenom} le montant est de {Montant:C}";
string v_result = StringUtilEx.FormatString(v_mask, v_pers);

MessageBox.Show(v_result);
}


using System;
using System.Collections;
using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;

namespace Net.Gavarin.Text
{
/// <summary>
/// La classe StringUtilEx permet de formatter les chaines en utilisant des chaines de
/// formattage nommée.
/// L'instance d'objet (p_dataSource) utilisé doit posséder des propriétés public.
/// </summary>
/// <example>
/// Exemple de chaine de formattage :
/// "Bonjour {Civilite} {Nom},"
/// </example>
public class StringUtilEx
{
#region private data memebers
private const string m_format = @"\{[\s\S]*?\}";
private const BindingFlags FLAGS_REFLECTION_ATTR =
BindingFlags.Public
BindingFlags.Static
BindingFlags.IgnoreCase
BindingFlags.Instance;
#endregion
#region constructors
public StringUtilEx()
{
}
#endregion
#region private methods
private static Regex GetRegex()
{
return new Regex(m_format, RegexOptions.Compiled);
}

private static object GetObjectProperty(object p_dataSource, string p_name)
{
PropertyInfo v_pi = p_dataSource.GetType().GetProperty(p_name, FLAGS_REFLECTION_ATTR);
if ( v_pi != null )
{
return v_pi.GetValue(p_dataSource, null);
}
else
return null;
}

private static void ExtractPropNameAndFormat(string p_value,
out string p_propName,
out string p_format)
{
string[] v_splits = p_value.Split(':');
p_propName = v_splits[0];

if ( v_splits.Length > 1 )
p_format = v_splits[1];
else
p_format = null;
}

private static string GetPropertyValue(
object p_dataSource,
string p_dataMember,
string p_nameAndFormat)
{
string v_format;
string v_name;
ExtractPropNameAndFormat(p_nameAndFormat, out v_name, out v_format);

int v_posSubProp = v_name.IndexOf(".");
if ( v_posSubProp != -1 )
{
string v_propMaster = v_name.Substring(0, v_posSubProp);
string v_subProp = v_name.Substring(v_posSubProp + 1,
v_name.Length - v_posSubProp - 1);

object v_obj = GetObjectProperty(p_dataSource, v_propMaster);
if ( v_obj == null )
return "";
else
{
if ( v_format != null )
v_subProp += ":" + v_format;
return GetPropertyValue(v_obj, null, v_subProp);
}
}

object v_value = GetObjectProperty(p_dataSource, v_name);

if ( v_value == null )
return "{" + v_name + "}";
else
{
IFormattable v_fmt = v_value as IFormattable;
if ( IsTrimEmpty(v_format) (v_fmt == null) )
return v_value.ToString();
else
{
try
{
return v_fmt.ToString(v_format, null);
//return string.Format("{0"+v_format+"}",v_value);
}
catch
{
return v_value.ToString();
}
}
}
}
#endregion
#region public methods
private static string ReplaceTags(string p_value)
{
return p_value.Replace("<", " ").Replace(">", " ");
}

private static bool IsEmpty(string p_value)
{
return (p_value == null)
(p_value.Length == 0);
}

private static bool IsTrimEmpty(string p_value)
{
return IsEmpty(p_value) (p_value.Trim().Length == 0);
}

/// <summary>
/// Formatte un chaine
/// Exemple de chaine de formattage :
/// "Bonjour {Civilite} {Nom},"
/// </summary>
/// <param name="p_format"></param>
/// <param name="p_dataSource"></param>
/// <returns></returns>
public static string FormatString(
string p_format,
object p_dataSource)
{
return FormatString(p_format, p_dataSource, null);
}

/// <summary>
/// Formatte un chaine
/// Exemple de chaine de formattage :
/// "Bonjour {Civilite} {Nom},"
/// </summary>
/// <param name="p_format"></param>
/// <param name="p_dataSource"></param>
/// <param name="p_dataMember"></param>
/// <returns></returns>
public static string FormatString(
string p_format,
object p_dataSource,
string p_dataMember)
{
if ( !IsTrimEmpty(p_format) )
{
string v_temp = p_format;
MatchCollection v_matchCollection = GetRegex().Matches(p_format);

foreach ( Match v_m in v_matchCollection )
{
if ( v_m.Groups.Count > 0 )
{
foreach ( Capture v_c in v_m.Groups[0].Captures )
{
string v_property = v_c.Value.Trim();
if ( (v_property != null) && (v_property.Length > 2) )
{
v_property = v_property.Substring(1, v_property.Length - 2);
if ( !IsTrimEmpty(v_property) )
{
v_temp = v_temp.Replace("{" + v_property + "}",
GetPropertyValue(p_dataSource, p_dataMember, v_property));
}
}
}
}
}
return v_temp;
}
else
return p_format;
}
#endregion
}
}


Et bien sur le code de PersonEntity


using System;
using System.Collections.Generic;
using System.Text;

namespace WindowsApplication3
{
class PersonEntity
{
#region Fields
private string m_nom = "";
private string m_prenom = "";
private int m_montant = 1;
#endregion
#region Constructors
public PersonEntity()
{
}
public PersonEntity(string p_nom, string p_prenom, int p_montant)
{
m_nom = p_nom;
m_prenom = p_prenom;
m_montant = p_montant;
}
#endregion
#region Properties
public string Nom
{
get
{
return m_nom;
}
set
{
m_nom = value;
}
}

public string Prenom
{
get
{
return m_prenom;
}
set
{
m_prenom = value;
}
}

public int Montant
{
get
{
return m_montant;
}
set
{
m_montant = value;
}
}
#endregion
}
}
 

0 comments so far.

Something to say?