使用ITypeConverter进行AutoMapper依赖注入

时间:2017-07-27 00:53:25

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

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

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

任何人都可以帮助我?

UserRepository:

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);
    }
}

2 个答案:

答案 0 :(得分:2)

您的预感是正确的:当您使用CreateUsing<TTypeConverter>()时,无法将任何参数注入构造函数。该类型必须具有无参数构造函数。

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

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

但我怀疑这样做是行不通的,因为你正在使用依赖注入试图在运行时处理用户的时区。

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

你应该:

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

这是处理日期和时区的更简洁方法。

答案 1 :(得分:0)

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