分享Automapper Resolver的最佳方式

时间:2015-06-15 20:36:53

标签: c# asp.net-mvc-5 automapper

我有一个viewmodel设置,其中包含指向服务器上文件的多个物理路径字符串。 我有虚拟目录指向服务器上的根文件夹。 我需要做的是将这些物理路径更改为引用虚拟文件夹的路径,这样我就可以在页面视图中创建超链接。

我希望做的是拥有一个可以传递密钥的公共解析器,然后让它返回我需要的路径。 我就是这样做的。我只是想看看是否有一个更简单的"更清洁"这样做的方式。 我只和mvc和c#一起工作了几个月,所以我还在学习。

提前感谢。

这是映射器信息

        Mapper.CreateMap<FAG_DETAIL, OrderFagDetail>()
            .ForMember(dest => dest.TXT01, opt => opt.ResolveUsing<DrawingPathCorrect>())
            .ForMember(dest => dest.TXT02, opt => opt.ResolveUsing<Prog1PathCorrect>())
            .ForMember(dest => dest.TXT03, opt => opt.ResolveUsing<Prog2PathCorrect>())
            .ForMember(dest => dest.TXT04, opt => opt.ResolveUsing<Prog3PathCorrect>())
            .ForMember(dest => dest.TXT05, opt => opt.ResolveUsing<Prog4PathCorrect>())
            .ForMember(dest => dest.TXT07, opt => opt.ResolveUsing<Procs1PathCorrect>())
            .ForMember(dest => dest.TXT08, opt => opt.ResolveUsing<Procs2PathCorrect>())
            .ForMember(dest => dest.TXT09, opt => opt.ResolveUsing<Procs3PathCorrect>())
            .ForMember(dest => dest.TXT10, opt => opt.ResolveUsing<Procs4PathCorrect>())
            .ForMember(dest => dest.TXT11, opt => opt.ResolveUsing<FASPathCorrect>())
            .ForMember(dest => dest.TXT06, opt => opt.ResolveUsing<SecondDrawingPathCorrect>());

这是ModelView以及我当前使用的解析器。作为OrderfagDetail的模型的模型FAG_DETAIL非常大,所以我不会在此处包含它。可以安全地假设在源代码中存在与ModelView属性完全匹配的属性。

public class OrderFagDetail
{
    public decimal NO { get; set; }
    public decimal FKNO { get; set; }
    public decimal TYP { get; set; }
    public string TXT01 { get; set; } //drawing link
    public string TXT02 { get; set; } //First Op program or L20 Program
    public string TXT03 { get; set; } //Second op program or K16 Program
    public string TXT04 { get; set; } //Third op Program
    public string TXT05 { get; set; } //Fourth op Program
    public string TXT06 { get; set; } //Second drawing
    public string TXT07 { get; set; } //First Op process sheet
    public string TXT08 { get; set; } //Second Op process sheet
    public string TXT09 { get; set; } //Third Op process sheet
    public string TXT10 { get; set; } //Fourth Op process sheet
    public string TXT11 { get; set; } //First Article link

}

public interface IValueResolver
{
    ResolutionResult Resolve(ResolutionResult source);
}

public class SecondDrawingPathCorrect : ValueResolver<FAG_DETAIL, string>
{
    protected override string ResolveCore(FAG_DETAIL detail)
    {  
        PathResolver pr = new PathResolver();
        return (pr.ResolvePath(detail.TXT06,"PDFs\\"));
    }
}
public class PathResolver
{   
 public string ResolvePath(string strSrc, string strKey)
   {
       string corrected = "";
        if (strSrc.Length > 0)
        {                
            string inputdetail = strSrc;
            corrected = inputdetail.Substring(inputdetail.IndexOf(strKey)+strKey.Length, inputdetail.Length - inputdetail.IndexOf(strKey)-strKey.Length);
        }

        return (corrected);
   }

}

2 个答案:

答案 0 :(得分:0)

为了改进,您可以将PathResolver类设置为static或singleton 不同的是 静态类:

  1. 您无法创建静态类的实例。
  2. 由.NET Framework公共语言运行库自动加载     (CLR)当加载包含该类的程序或命名空间时。
  3. 静态类不能有构造函数。
  4. 我们无法将静态类传递给方法。
  5. 我们不能将静态类继承到C#中的另一个静态类。
  6. 的Singleton:

    1. 您可以创建一个对象实例并重复使用它。
    2. Singleton实例是第一次在用户创建时创建的     请求。
    3. Singleton类可以有构造函数。
    4. 您可以创建singleton类的对象并将其传递给方法。
    5. Singleton类没有说任何继承限制。
    6. 我们可以处理单例类的对象,但不能处理静态的对象     类。

答案 1 :(得分:0)

假设您有多个这样的CreateMaps:

Mapper.CreateMap<PdfFileObject, MyViewModel>()
    .ForMember( d => d.Uri, opt => opt.ResolveUsing(something with "pdfs")
Mapper.CreateMap<ImageFileObject, MyViewModel>()
    .ForMember( d => d.Uri, opt => opt.ResolveUsing(something with "images")
..etc

像这样创建你的解析器:

public class SecondDrawingPathCorrect<TFILE> : ValueResolver<FAG_DETAIL, string>
where TFILE : FAG_DETAIL
{
    private readonly string _replaceKey;
    public SecondDrawingPathCorrect(string replaceKey)
    {
        _replaceKey = replaceKey;
    }

    protected override string ResolveCore(FAG_DETAIL detail)
    {   
        string corrected = "";
        if (detail.TXT06.Length > 0)
        {                
            string inputdetail = detail.TXT06;
            corrected = inputdetail.Substring(inputdetail.IndexOf(_replaceKey) + 5, inputdetail.Length - inputdetail.IndexOf("_replaceKey) - 5);
        }

        return corrected;
    }
}

像这样注册您的地图:

Mapper.CreateMap<PdfFileObject, MyViewModel>()
    .ForMember( d => d.Uri, opt => opt.ResolveUsing(new SecondDrawingPathCorrect<PdfFileObject>("PDFs");

为了使上述工作正常,您的PfdFileObject,ImageFileObject等应该实现/继承FAG_DETAIL。

还有另一个选项,如果你可以控制FAG_DETAIL,你可以在其上公开一个属性字符串FilePathPrefix(对于PdfFileObject将返回&#34; PDF&#34;)。然后你可以在解析器本身中使用它(即在&#34;替换&#34;部分使用detail.FilePrefix而不是_replaceKey)。

使用最新版本,您可以删除解析器的通用部分,并按照以下方式进行注册:

Mapper.CreateMap<FAG_DETAIL, MyViewModel>()
        .ForMember( d => d.Uri, opt => opt.ResolveUsing<SecondDrawingPathCorrect>()
.Include<PdfFileObject, MyViewModel>()
.Include<ImageFileObject, MyViewModel>()
...more includes;