.net 设计一个数据模型到平面文件转换。。。委托还是继承?
我有一个维护应用程序,它必须将企业数据(来自各种数据库/表)转换为平面文件,每个文件都具有特定的格式,供遗留应用程序使用。我有这样的数据模型.net 设计一个数据模型到平面文件转换。。。委托还是继承?,.net,inheritance,delegates,class-design,transformation,.net,Inheritance,Delegates,Class Design,Transformation,我有一个维护应用程序,它必须将企业数据(来自各种数据库/表)转换为平面文件,每个文件都具有特定的格式,供遗留应用程序使用。我有这样的数据模型 public class StatusCode { public String Id { get; set; } public Char Level { get; set; } public String Description { get; set; } } 我将从数据源中选择这些记录的一些子集或全部。我需要将每个实体映射到文件
public class StatusCode
{
public String Id { get; set; }
public Char Level { get; set; }
public String Description { get; set; }
}
我将从数据源中选择这些记录的一些子集或全部。我需要将每个实体映射到文件的一行,这可能需要调整数据(填充、转换或处理null
)
此解决方案在具体类中爆炸,但它们与映射委托一样薄。而且我觉得与IFileCreator和工厂一起工作更舒服。(同样,仅在必要时)
我假设一些基类是有用的,因为StringBuilder
循环和Byte[]
编码非常简单。具体类是否应该在基类中设置委托属性(而不是调用抽象方法)?我是否应该在方法上保留类型参数(以及这将如何影响基类/具体类)
我愿意找到任何解决办法。我的主要目标是易于维护。我现在有12个模型/文件,这可能会增加到21个。我可能需要在任何文件中插入任意页眉/页脚行(这就是为什么我喜欢可重写的基类方法Map)。您是否必须为每个可能的映射创建具体的子类?也许可以使用XML文件(或数据库)来描述每种文件的格式/内容。然后有一个类,它接受一个“FileType”键,并使用XML中的格式信息来确定如何为该文件类型构建文件。现在我已经编写了一些转换,我倾向于按类映射的方法,。我必须能够对伪造的模型运行单元测试,以确保正确构建文件(针对已知的良好示例文件测试它们) 我一直在将映射代理私有化到它们所属的“工作流”类(每个模型/文件一个“工作流”)。我必须将它们公开以进行单元测试,或者输出中间文件内容(工作流将完成的文件保存到数据存储)
每个类的映射似乎更加可测试和可分解。我认为这与使用映射委托是相同的解决方案。@ajmastrean-现在我更仔细地看了一下,你是对的。至于如何在不知道“T”是什么的情况下实现这一点,您只需要使用反射来获取所有属性,因此您实际上不需要知道对象的类型。我还考虑在每个具体类中重写抽象属性MapEntity(delegate)。与重写方法映射(T)的效果相同。不同的外观。
public delegate String MapEntity<T>(T entity);
public MapEntity<StatusCode> MapStatusCode = delegate(StatusCode entity)
{
return String.Format("{0},{1},{2}",
entity.Id.PadLeft(3, '0'),
entity.Level == 'S' ? 0 : 1,
entity.Description ?? "-");
}
public interface IFileCreator
{
Byte[] Create<T>(MapEntity<T> map, IEnumerable<T> entities);
}
public class DefaultFileCreator : IFileCreator
{
public Byte[] Create<T>(MapEntity<T> map, IEnumerable<T> entities)
{
StringBuilder sb = new StringBuilder();
foreach (T entity in entities)
sb.AppendLine(map(entity));
return Encoding.Default.GetBytes(sb.ToString());
}
}
...
fileCreator.Create(MapStatusCode, repository<StatusCode>.FindAll());
...
public interface IFileCreator<T>
{
Byte[] Create(IEnumerable<T> entities);
}
public abstract class FileCreator : IFileCreator<T>
{
protected abstract String Map(T entity);
public Byte[] Create(IEnumerable<T> entities)
{
StringBuilder sb = new StringBuilder();
foreach (T entity in entities)
sb.AppendLine(Map(entity));
return Encoding.Default.GetBytes(sb.ToString());
}
}
public class StatusCodeFile : FileCreator<StatusCode>
{
public override String Map(T entity)
{
return String.Format("{0},{1},{2}",
entity.Id.PadLeft(3, '0'),
entity.Level == 'S' ? 0 : 1,
entity.Description ?? "-");
}
}