繁体   English   中英

如何在Automapper类C#中编写方法

[英]How to write method in automapper class c#

我正在尝试在AutoMapper类中编写方法。 我的情况如下。

ClinicListVm = AutoMapperConfig.mapper
  .Map<GetClinicsByUserName_Result, ClinicListViewModel>(c);

现在我已经将ClinicListViewModel与GetClinicsByUserName_Result映射了,我想按如下方式操纵目标模型中的一个属性。

ClinicListVm.ProgressBarCssClass = string.Empty;
if (ClinicListVm.PercentComplete == 100)
{
  ClinicListVm.ProgressBarCssClass = "progress-bar-success";
}
else if (DateTime.Now.Subtract(ClinicListVm.BillerStartDateTime ?? DateTime.Now).TotalDays > MaxDaysInDataEntry)
{
  // partial is a warning color
  ClinicListVm.ProgressBarCssClass = "progress-bar-partial";
}

因此,我如何将这些代码本身包含在automapper类中。

谢谢

我个人认为@Rajmond Burgaj的答案很不错。 在这种情况下,使用ResolveUsing()或自定义解析器是一个好方法。

但是,我只想分享一个更务实的选择,它可能会带来相同的效果,并可能在将来对您有所帮助。 您可能需要考虑将条件if ... then ...逻辑分离到一个单独的函数。 例如:

private string DetermineProgressBarState(SourceClass source)
{
    if (source.PercentComplete == 100) return "progress-bar-success";

    var MaxDaysInDataEntry = 42; // missing in your sample
    return DateTime.Now.Subtract(source.BillerStartDateTime ?? DateTime.Now).TotalDays > MaxDaysInDataEntry 
        ? "progress-bar-partial" 
        : null;
}

这样,您可以轻松地将其映射到您的配置中,如下所示:

Mapper.Initialize((config =>
{
    config.CreateMap<SourceClass, TargetClass>()
        .ForMember(
            dest => dest.ProgressBarCssClass, 
            opt => opt.MapFrom(src =>  DetermineProgressBarState(src))
        );
}));

完全按照您的预期运行。 这是完整的示例,作为XUnit测试(但您会看到图):

public class SourceClass
{
    public int PercentComplete { get; set; }
    public DateTime? BillerStartDateTime { get; set; }
}

public class TargetClass
{
    public string ProgressBarCssClass { get; set; }
}

public class UnitTest1
{
    [Fact]
    public void Test1()
    {
        // arrange - configure the automapper
        Mapper.Initialize((config =>
        {
            config.CreateMap<SourceClass, TargetClass>()
                .ForMember(
                    dest => dest.ProgressBarCssClass, 
                    opt => opt.MapFrom(src =>  DetermineProgressBarState(src))
                );
        }));

        // arrange - create a 
        var source = new SourceClass() { PercentComplete = 100 };

        // act - map source to target
        var target = Mapper.Map<TargetClass>(source);

        // assert - verify the result
        target.ProgressBarCssClass.Should().Be("progress-bar-success");
    }

    private string DetermineProgressBarState(SourceClass source)
    {
        if (source.PercentComplete == 100) return "progress-bar-success";

        var MaxDaysInDataEntry = 42; // missing in your sample
        return DateTime.Now.Subtract(source.BillerStartDateTime ?? DateTime.Now).TotalDays > MaxDaysInDataEntry 
            ? "progress-bar-partial" 
            : null;
    }
}

但是...我完全同意以下意见: AutoMapper不是放置此逻辑的地方 原因是您实际上是在映射逻辑中定义标记逻辑(html / css数据)。 最好将其放置在视图中(大概是.cshtml)。

考虑到这一点,如果您将来选择以某种“正确的方式”重构此方法,那么DetermineProgressBarState()函数仍然会有所帮助。 您只需将代码从AutoMapper配置移动到控制器(或.cshtml帮助器)。

如果要在映射时执行另一个功能,则可以使用ResolveUsing方法并将逻辑放在其中。

CreateMap<GetClinicsByUserName_Result, ClinicListViewModel>()
.ForMember(d => d.ProgressBarCssClass , o => o.ResolveUsing(s =>
{
    //Do your custom logic here.
}))
.AfterMap((src, dest) =>
{
   //Do your logical after mapping has been done
    dest.ProgressBarCssClass = string.Empty;
    if (dest.PercentComplete == 100)
    {
       dest.ProgressBarCssClass = "progress-bar-success";
    }
    else if (DateTime.Now.Subtract(dest.BillerStartDateTime ?? 
    DateTime.Now).TotalDays > MaxDaysInDataEntry)
    {
       // partial is a warning color
       dest.ProgressBarCssClass = "progress-bar-partial";
    }      
});

不太确定MaxDaysInDataEntry的来源,但是如果可以在此方法中检索它,则可以采用这种方式,否则,如果MaxDaysInDataEntry是从其他地方的业务逻辑生成的变量,那么这是一个问题!

无论如何,请让我知道它是否有帮助以及该变量的来源!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM