1

我的想法是将带有string.Format()占位符 {0}...{n} 的文本存储在数据库中。占位符值类型以逗号分隔格式 (CSV) 存储在另一个名为“参数”的数据库字段中。

数据库中的文本示例:

发件人:{0}
地址:{1}

收件人:{2}
地址:{3}

“参数”字段包含:

Company.FullName、Company.Address.FullAddress、Customer.FullName、Customer.Address.FullAddress

我希望“公司”、“客户”和“地址”代表类是显而易见的。FullNameFullAddress代表返回字符串的属性。“公司”和“客户对象能够根据请求加载正确的地址

我正在考虑使用带有string.Format()的“ params object[] params ”来传递值。

现在的问题是如何加载正确的对象并将匹配的参数计数传递给string.Format方法?

要求

  1. 数据库中的文本必须是可编辑的;
  2. 占位符计数可能会更改(添加或删除);
  3. 每个占位符在“ Parameters ”数据库字段中都有对应的参数;
  4. 每个参数代表一个名及其属性。可以调用子类,但它们必须用点 (.) 分隔。示例:Company.Address.FullAddress
  5. 仅应创建或加载特定于数据库中文本的所需对象。为了以防万一,加载一堆对象不是一个好主意;
  6. 如果只有一种方法可以处理该任务,那就太好了;
  7. 如果有任何合适的图案,请使用任何图案或图案。也许是CompositeFactoryBuilder模式?

作为解决方案,我看到:

  1. 硬编码为每个数据库记录加载的对象。这要求不能更改带有占位符的文本。所以这个解决方案不适合我。
  2. 使用每个参数的反射加载对象。这将是一个很好的动态方法,但是如何使用客户地址信息加载正确的“地址”对象呢?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。目前LoadTemplateContentFromDbLoadTemplateParametersFromDb对数据库进行两次单独的调用,但我将对其进行重构,以便一次询问整个模板信息。

4

1 回答 1

0

一旦你有了对象,以及它的属性的字符串,我为其他东西编写的这些方法可能会有所帮助:

/// <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()

于 2011-05-06T07:39:38.220 回答