Reputation: 529
I want to use a dictionary to replace words in a HTML template between two $ signs. I've got it working when I add the keys myself, but I want to be able to replace using reflection, so that if I give this project to someone else, then they only need to change the class and the template keys.
I've got the Class with some properties. I populate this class and then try to populate the dictionary.
public class FeedMessageValue
{
public string Username { get; set; }
public string SubscriptionID { get; set; }
public DateTime MessageTime { get; set; }
}
public class FeedMessageData : IMailData
{
private FeedMessageValue feedMessageValue;
public FeedMessageData(string username, string subscriptionID, DateTime messageTime)
{
this.feedMessageValue = new FeedMessageValue
{
Username = username
, SubscriptionID = subscriptionID
, MessageTime = messageTime
};
PropertyInfo[] infos = this.feedMessageValue.GetType().GetProperties();
foreach (PropertyInfo info in infos)
{
this.getMergeValues().Add(info.Name, info.GetValue(this.feedMessageValue, null).ToString());
}
}
public Dictionary<string, string> getMergeValues()
{
return new Dictionary<string, string>();
}
}
This runs through the Email Generator:
public interface IMailData
{
Dictionary<string, string> getMergeValues();
}
public interface IEmailGenerator
{
MailMessage generateEmail(IMailData mailData, string htmlTemplate, string textTemplate);
}
public class EmailGenerator : IEmailGenerator, IRegisterInIoC
{
// Setup the rules
static readonly Regex emailRegex = new Regex(@"\$([\w\-\,\.]+)\$", RegexOptions.Compiled);
private string mergeTemplate(string template, IReadOnlyDictionary<string, string> values)
{
string emailTextData = emailRegex.Replace(template, match => values[match.Groups[1].Value]);
return emailTextData;
}
public MailMessage generateEmail(IMailData mailData, string htmlTemplate, string textTemplate)
{
// MailMessage
}
}
So, in theory one of the dictionary keyvalue pairs should now be {"Username", username}, but using my code to replace for $Username$, then it throws a bug with that there is no key for Username.
Upvotes: 1
Views: 913
Reputation: 3539
The problem is with getMergeValues()
. You're creating a new instance of Dictinary<string, string>
each time. Change that method to a property, or have it return a field.
As it is right now, when you're looping through the PropertyInfo[]
, you create a new instance of Dictionary<string, string>
, add { "Username", username }
, then don't do anything with the reference to the Dictionary<string, string>
you created. Then on the next iteration of the loop you create a second Dictionary<string, string>
this one with, perhaps, { SubscriptionId, subscriptionID }
, and don't do anything with the reference. And so on and so on.
public class FeedMessageData : IMailData
{
private FeedMessageValue feedMessageValue;
public FeedMessageData(string username, string subscriptionID, DateTime messageTime)
{
MergeData = new Dictionary<string, string>();
this.feedMessageValue = new FeedMessageValue
{
Username = username
, SubscriptionID = subscriptionID
, MessageTime = messageTime
};
PropertyInfo[] infos = this.feedMessageValue.GetType().GetProperties();
foreach (PropertyInfo info in infos)
{
MergeData.Add(info.Name, info.GetValue(this.feedMessageValue, null).ToString());
}
}
public Dictionary<string, string> MergeData { get; }
}
Upvotes: 1