Как инициализировать объект из строки (имени класса) для массива объекта params string.Format? - PullRequest
1 голос
/ 06 мая 2011

Моя идея состоит в том, чтобы хранить текст с string.Format () заполнителями {0} ... {n} в базе данных. Типы значений заполнителя хранятся в другой базе данных поле , которое называется «Параметры» в формате с разделителями-запятыми (CSV).

Пример текста в базе данных:

Отправитель: {0}
Адрес: {1}

Получатель: {2}
Адрес: {3}

А поле «Параметры» содержит:

Company.FullName, Company.Address.FullAddress, Customer.FullName, Customer.Address.FullAddress

Надеюсь, очевидно, что " Company ", " Customer " и " Address " представляют классы. FullName и FullAddress повторяющиеся свойства , которые возвращают строку . Объекты Company и Customer * могут правильно загрузить Адрес по запросу.

Я собираюсь использовать « params object [] params » с string.Format () для передачи значений.

Теперь вопрос заключается в том, как загрузить правильные объекты и передать соответствующий счетчик параметров в строку . Формат метод?

Требования

  1. Текст в базе данных должен быть редактируемым;
  2. Число заполнителей может быть изменено (добавлено или удалено);
  3. Каждый заполнитель имеет соответствующий параметр в поле базы данных " Параметры ";
  4. Каждый параметр представляет имя класса и его свойство . Подклассы могут быть вызваны, но они должны быть разделены точкой (.). Пример: Company.Address.FullAddress ;
  5. Требуется только объект , специфичный для текста в базе данных, должен быть создан или загружен. На всякий случай не стоит загружать кучу объектов;
  6. Было бы замечательно, если бы только один метод мог справиться с задачей;
  7. Используйте любой шаблон или шаблоны, если они есть. Может быть, Composite , Factory или Builder pattern, возможно?

В качестве решения вижу:

  1. Жесткий код загрузки объектов для каждой записи базы данных. Это требует, чтобы текст с заполнителями не мог быть изменен. Так что это решение мне не подходит.
  2. Загрузить объект (ы), используя отражений на параметр. Это был бы хороший динамический способ сделать это, но как загрузить правильный объект " Address " с адресом Customer или это? Объект Customer создается / загружается по его CustomerId .

Пока я так далеко:

    public string FillTemplate(int languageId, long templateTypeId, params object[] parameters)
    {
        string formatStringFromDb = LoadTemplateContentFromDb(languageId, templateTypeId);

        return string.Format(formatStringFromDb, parameters);
    }

    public object[] LoadTemplateParameter(int languageId, long templateTypeId)
    {
        string csvTemplateParameters = LoadTemplateParametersFromDb(languageId, templateTypeId);
        string[] stringParameters = csvTemplateParameters.Split(',');
        object[] templateParametersToReturn = new object[stringParameters.Length];

        for (int i = 0; i < stringParameters.Length; i++)
        {
            // Split class name(s) and property
            string[] classAndPropertyNames = stringParameters[i].Split('.');

            // Initialise and add the object to the parameter object array
            templateParametersToReturn[i] = InitialiseParameterObject(classAndPropertyNames);
        }

        return templateParametersToReturn;
    }

    private static object InitialiseParameterObject(string[] classAndPropertyNames)
    {
        // Now what? How do I create new object(s) from a string?
        // To create a Customer or Company class an appropriate ID is needed.
        // How do I know which ID (Customer or Company)
        // do I need to provide in advance?
        throw new NotImplementedException();
    }

Спасибо, если сможете прочитать это далеко. Еще лучше, если у вас есть идеи для меня:)

PS. В настоящее время LoadTemplateContentFromDb и LoadTemplateParametersFromDb делают два отдельных вызова базы данных, но я проведу ее рефакторинг, чтобы сразу запрашивать всю информацию шаблона.

1 Ответ

0 голосов
/ 06 мая 2011

Когда у вас есть объект и строка для его свойств, эти методы, которые я написал для чего-то другого, могут помочь:

/// <summary>
/// Gets an object property's value, recursively traversing it's properties if needed.
/// </summary>
/// <param name="FrameObject">The object.</param>
/// <param name="PropertyString">The object property string.
/// Can be the property of a property. e.g. Position.X</param>
/// <returns>The value of this object's property.</returns>
private object GetObjectPropertyValue(Object FrameObject, string PropertyString)
{
    object Result = FrameObject;

    string[] Properties = PropertyString.Split('.');

    foreach (var Property in Properties)
    {
        Result = Result.GetType().GetProperty(Property).GetValue(Result, null);
    }

    return Result;
}

public Type GetObjectPropertyType(string ObjectName, string PropertyString)
{
    Object Result = GetObjectByName(ObjectName);

    string[] Properties = PropertyString.Split('.');

    foreach (var Property in Properties)
    {
        Result = Result.GetType().GetProperty(Property).GetValue(Result, null);
    }

    return Result.GetType();
}

Чтобы получить его в string.Format(), вы можете использовать вышеописанные методыот массива строк свойств, до самих свойств.Затем вы передадите это как последний аргумент os string.Format().

...