【问题标题】:AutoMapper Dependency Injection with ITypeConverter使用 ITypeConverter 的 AutoMapper 依赖注入
【发布时间】:2017-07-27 00:53:24
【问题描述】:

我正在尝试使用 Automapper 将我的所有 DateTimes 从 UTC 转换为本地时间,但我需要将接口注入 ITypeConverter...当我运行应用程序时收到此错误:MissingMethodException: No为此对象定义的无参数构造函数。

我认为问题出在依赖注入代码上!

谁能帮帮我?

用户存储库:

public class UserRepository : IUserRepository
{
    private static readonly MapperConfiguration Config = new MapperConfiguration(cfg =>
    {
        cfg.CreateMap<User, User>();

        cfg.CreateMap<DateTime?, DateTime?>().ConvertUsing<UtcToLocalConverter>();
    });

    public List<User> GetById(string[] ids)
    {
        var result = BuildQuery().Where(w => ids.Contains(w.UserName)).ToList();

        var mapper = Config.CreateMapper();

        return mapper.Map<List<User>>(result); // Throws error !!!
    }

    #region Helper

    private IQueryable<User> BuildQuery()
    {
        return Settings.EpedDb.User;
    }

    #endregion
}

转换器

public class UtcToLocalConverter : ITypeConverter<DateTime?, DateTime?>
{
    public UtcToLocalConverter(IBaseSettings baseClass) // I tried to inject here!!!
    {
        Settings = baseClass;
    }

    private IBaseSettings Settings { get; }

    public DateTime? Convert(DateTime? source, DateTime? destination, ResolutionContext context)
    {
        if (source == null) return null;

        var tzi = TimeZoneInfo.FindSystemTimeZoneById(Settings.UserData.TimeZone);
        return TimeZoneInfo.ConvertTime(DateTime.SpecifyKind((DateTime)source, DateTimeKind.Utc), tzi);
    }
}

【问题讨论】:

  • 请不要将代码发布为截图图像。您可以将相关代码复制并粘贴到您的问题中吗?
  • @NateBarbettini 感谢您的建议!您对此有何看法?

标签: dependency-injection asp.net-core .net-core automapper typeconverter


【解决方案1】:

您的预感是正确的:当您使用CreateUsing&lt;TTypeConverter&gt;() 时,您不能将任何参数注入到构造函数中。该类型必须有一个无参数的构造函数。

您可以将单个实例传递给CreateUsing()

var converter = new UtcToLocalConverter(mySettings);
cfg.CreateMap<DateTime?, DateTime?>().ConvertUsing(converter);

但我怀疑这不起作用,因为您正在使用依赖注入来尝试在运行时处理用户的时区。

我认为真正解决您的问题的方法是不在应用程序的这一层处理时区。 .NET DateTime 类在处理时区方面是出了名的糟糕。

你应该:

  • 使用DateTimeOffset? 代替DateTime?
  • 始终以 UTC(偏移量 0)存储日期
  • 不用担心在应用程序代码中转换时区
  • 在渲染或表示层,以用户本地时区渲染 UTC 日期

这是处理日期和时区的一种更简洁的方式。

【讨论】:

    【解决方案2】:

    @NateBarbettini 说的很有道理,但这可以使用ConstructServicesUsing 来完成。文档是here

    【讨论】: