有时,我需要一种方法来更改(或一组)显示名称(格式、顺序等)。问题是,为了更改像列的显示名这样简单的内容,我就不得不推动生产。为了解决这个问题,我们决定将这些元数据信息存储到数据库中(或者其他任何地方)。
public interface IMetadata
{
String ObjectFullName { get; set; } // Including namespace, used as key.
String PropertyName { get; set; } // Excluding namespace, used as short-key.
String DisplayName { get; set; }
String DisplayFormat { get; set; }
Int32 DisplayOrder { get; set; }
}public interface IMetadataContainer
{
IDictionary<String, IMetadata> Metadata { get; set; }
}public interface IMetadataProvider
{
String ObjectFullName { get; set; }
void Fill(IMetadataContainer container, IEnumerable<IMetadata> metadataSource, Boolean prefixObjectFullName);
}public class MetadataBase : IMetadata
{
public String ObjectFullName { get; set; }
public String PropertyName { get; set; }
public String DisplayName { get; set; }
public String DisplayFormat { get; set; }
public Int32 DisplayOrder { get; set; }
public MetadataBase(String objectFullName, String propertyName) : this(objectFullName, propertyName, "", "{0}", Int32.MaxValue) { }
public MetadataBase(String objectFullName, String propertyName, String displayName = "", String displayFormat = "{0}", Int32 displayOrder = Int32.MaxValue)
{
this.ObjectFullName = objectFullName;
this.PropertyName = propertyName;
this.DisplayName = String.IsNullOrWhiteSpace(displayName) ? this.PropertyName : displayName;
this.DisplayFormat = displayFormat;
this.DisplayOrder = displayOrder;
}
}public class MetadataContainerBase : IMetadataContainer
{
public IDictionary<String, IMetadata> Metadata { get; set; }
public MetadataContainerBase(IEnumerable<IMetadata> metadata)
{
this.Metadata = metadata.ToDictionary(m => m.PropertyName, m => m);
}
}public class MetadataProviderBase : IMetadataProvider
{
public String ObjectFullName { get; set; }
public MetadataProviderBase(Type type) : this(type.FullName) { }
public MetadataProviderBase(String objectFullName)
{
this.ObjectFullName = objectFullName;
}
/// <summary>
/// Fills the container with the metadata.
/// </summary>
/// <param name="fullName">Full name of the object whose metadata you'd like to put into the container.</param>
/// <param name="container">Object receiving the metadata.</param>
/// <param name="metadataSource">Collection of some/all metadata available.</param>
/// <param name="prefixObjectFullName">If true, the key for each piece of metadata will be the object's full name followed by the property's name.</param>
public static void Fill(String fullName, IMetadataContainer container, IEnumerable<IMetadata> metadataSource, Boolean prefixObjectFullName)
{
// VALIDATE:
if (container == null) { return; }
container.Metadata = container.Metadata ?? new Dictionary<String, IMetadata>();
// FILL:
IEnumerable<IMetadata> metas = metadataSource.Where(m => m.ObjectFullName == fullName);
if (metas == null || !metas.Any()) { return; }
foreach (IMetadata meta in metas)
{
String key = prefixObjectFullName ? meta.ObjectFullName + meta.PropertyName : meta.PropertyName;
container.Metadata.AddOrReplace(key, meta);
}
}
}这种结构中有什么地方可能会使其不太容易扩展或恢复呢?这是我的主要目标,我也尽我最大的努力来编写可读性很强的代码。
如果你对这些领域有任何建议(或任何其他领域真的),我很乐意听到它们!
发布于 2015-04-22 13:27:38
if (container == null) { return; }这里的括号是不必要的,可以去掉。这很可能是你喜欢的风格(坦白地说,我更喜欢所有的身体都在自己的线上,用牙套围起来)。
public interface IMetadata
{
String ObjectFullName { get; set; } // Including namespace, used as key.
String PropertyName { get; set; } // Excluding namespace, used as short-key.
String DisplayName { get; set; }
String DisplayFormat { get; set; }
Int32 DisplayOrder { get; set; }
}您使用了偶尔的注释来清除接口中的意图,但是如果将这些注释合并到适当的XML注释结构中,这些注释将更加有用。如果您的目标是重用这些接口,那么对您的接口进行完整XML注释的好处将是显而易见的,如果您打算让其他人使用它们的话,就会更加明显。
另外,Stylecop建议您使用string和int和bool结束String和Int32和Boolean.显然,这是一个风格问题,但我肯定认为int比Int32更具可读性。
您的// VALIDATE:和// FILL:注释没有添加任何内容。从代码中可以很明显地看出位元是做什么的。使用非XML注释来解释为什么要以自己的方式做事,而不是用什么方法。
https://codereview.stackexchange.com/questions/87469
复制相似问题