Заполнение словаря из класса с помощью отражения - PullRequest
1 голос
/ 11 июня 2019

Я хочу использовать словарь для замены слов в шаблоне HTML между двумя знаками $.У меня все работает, когда я сам добавляю ключи, но я хочу иметь возможность заменить с помощью отражения, так что, если я передам этот проект кому-то еще, им нужно только изменить класс и ключи шаблона.

У меня есть класс с некоторыми свойствами.Я заполняю этот класс и затем пытаюсь заполнить словарь.

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>();
    }
}

Это выполняется через генератор электронной почты:

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
    }
}

Итак, теоретически одна из пар значений ключа словаря теперь должна быть{"Имя пользователя", имя пользователя}, но используя мой код вместо $ Username $, возникает ошибка, связанная с отсутствием ключа для имени пользователя.

1 Ответ

1 голос
/ 11 июня 2019

Проблема с getMergeValues(). Вы создаете новый экземпляр Dictinary<string, string> каждый раз. Измените этот метод на свойство или попросите его вернуть поле.

Как сейчас, когда вы просматриваете PropertyInfo[], вы создаете новый экземпляр Dictionary<string, string>, добавляете { "Username", username }, а затем ничего не делаете со ссылкой на Dictionary<string, string>, которую вы создано. Затем на следующей итерации цикла вы создаете второй Dictionary<string, string> этот, возможно, с { SubscriptionId, subscriptionID }, и ничего не делаете со ссылкой. И так далее, и так далее.

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; }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...