Reputation: 43
I want to bind a dynamic object to a string like replacing the instance.field in string to the real value of the instance.
See my code below to understand:
String body = "My Name is: model.Name";
Model model = new Model();
model.Name = "Mohammed";
String result = ReplaceMethod(body,model);
// result is, My Name is: Mohammed
Note: I want to use this procedure in big string value with too many fields. Thanks.
Upvotes: 1
Views: 1482
Reputation: 1505
I created an extension based on Alexy's answer.
public static class StringExtensions
{
public static string BindTo<T>(this string body, T model) where T : class
{
Regex regex = new Regex(@"{([a-zA-Z]+[0-9]*)}");
var matches = regex.Matches(body).Cast<Match>()
.OrderByDescending(i => i.Index);
foreach (Match match in matches)
{
var fullMatch = match.Groups[0];
var propName = match.Groups[1].Value;
object value = string.Empty;
try
{
// use reflection to get property
// Note: if you need to use fields use GetField
var prop = typeof(T).GetProperty(propName);
if (prop != null)
{
value = prop.GetValue(model, null);
}
}
catch (Exception ex)
{
//TODO Logging here
}
// remove substring with pattern
// use remove instead of replace, since
// you may have several the same string
// and insert what required
body = body.Remove(fullMatch.Index, fullMatch.Length)
.Insert(fullMatch.Index, value.ToString());
}
return body;
}
}
That way you can call it like this.
body = body.BindTo(model);
Edit: You could also use Mustache# which is based on the awesome mustache library.
In situations where you need much fewer properties to be bound, you could use tools like AutoMapper or create anonymous objects as you go along. For example:
body = body.BindTo(new { model.Name, model.Email });
Best of luck!
Upvotes: 0
Reputation: 1936
I wouldn't use perfix in string like "model.Name", I would go right away with {Name}. What we need is to find all of them, Regex can help us with this.
Try this method, check comments:
class Program
{
static void Main(string[] args)
{
String body = "My Name is: {Name} {LastName}";
Model model = new Model();
model.Name = "Mohammed";
model.LastName = "LastName";
String result = ReplaceMethod(body, model);
}
private static string ReplaceMethod(string body, Model model)
{
// can't name property starting with numbers,
// but they are possible
Regex findProperties = new Regex(@"{([a-zA-Z]+[0-9]*)}");
// order by desc, since I want to replace all substrings correctly
// after I replace one part length of string is changed
// and all characters at Right are moved forward or back
var res = findProperties.Matches(body)
.Cast<Match>()
.OrderByDescending(i => i.Index);
foreach (Match item in res)
{
// get full substring with pattern "{Name}"
var allGroup = item.Groups[0];
//get first group this is only field name there
var foundPropGrRoup = item.Groups[1];
var propName = foundPropGrRoup.Value;
object value = string.Empty;
try
{
// use reflection to get property
// Note: if you need to use fields use GetField
var prop = typeof(Model).GetProperty(propName);
if (prop != null)
{
value = prop.GetValue(model, null);
}
}
catch (Exception ex)
{
//TODO Logging here
}
// remove substring with pattern
// use remove instead of replace, since
// you may have several the same string
// and insert what required
body = body.Remove(allGroup.Index, allGroup.Length)
.Insert(allGroup.Index, value.ToString());
}
return body;
}
public class Model
{
public string Name { get; set; }
public string LastName { get; set; }
}
}
Upvotes: 3