如何从string.Format params对象数组的字符串(类名)初始化对象?

时间:2011-05-06 07:27:28

标签: c# reflection initialization string.format

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

数据库中文本的示例:

  

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

     

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

“参数”字段包含:

  

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

我希望很明显“公司”,“客户”和“地址”代表类。返回字符串 FullName FullAddress reperesent 属性。 “公司”和“客户对象可以根据请求加载正确的地址

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

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

要求

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

    1. 对每个数据库记录加载的对象进行硬编码。这要求带有占位符的文本不能更改。所以这个解决方案不适合我。
    2. 每个参数使用反射加载对象。这将是一个很好的动态方式,但如何使用客户地址信息加载正确的“地址”对象呢?客户对象由 CustomerId 创建/加载。
    3. 到目前为止,我到目前为止:

          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 :(得分: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()传递。