web-dev-qa-db-ja.com

マッパーが初期化されていないことを示すオートマッパーエラー

Automapper 5.2を使用しています。基礎として使用しました this リンク。 Automapperのセットアッププロセスを段階的に説明します。

最初示されているように、Project.jsonにAutomapperを追加しました:

PM> Install-Package AutoMapper

Second「マッピング」と呼ばれるマッピングに関連するすべてのファイルを保持するフォルダーを作成しました

Thirdマッピングフォルダー内の独自のファイルでAutomapperの構成をセットアップしました。

public class AutoMapperConfiguration
{
    public MapperConfiguration Configure()
    {
        var config = new MapperConfiguration(cfg =>
        {
            cfg.AddProfile<ViewModelToDomainMappingProfile>();
            cfg.AddProfile<DomainToViewModelMappingProfile>();
            cfg.AddProfile<BiDirectionalViewModelDomain>();
        });
        return config;
    }
}

Forthまた、マッピングフォルダー内の独自のファイルで、次のようにマッピングプロファイルを設定しました。

public class DomainToViewModelMappingProfile : Profile
{
    public DomainToViewModelMappingProfile()
    {
        CreateMap<Client, ClientViewModel>()
           .ForMember(vm => vm.Creator, map => map.MapFrom(s => s.Creator.Username))
           .ForMember(vm => vm.Jobs, map => map.MapFrom(s => s.Jobs.Select(a => a.ClientId)));
    }
}

5番目、マッピングフォルダーにも独自のファイルとして拡張メソッドを追加しました...これは次にstartup.csで使用されました:

public static class CustomMvcServiceCollectionExtensions
{
    public static void AddAutoMapper(this IServiceCollection services)
    {
        if (services == null)
        {
            throw new ArgumentNullException(nameof(services));
        }
        var config = new AutoMapperConfiguration().Configure();
        services.AddSingleton<IMapper>(sp => config.CreateMapper());
    }
}

6番目Startup.csのConfigureServicesメソッドにこの行を追加しました

        // Automapper Configuration
        services.AddAutoMapper();

最後に、コレクションを変換するためにコントローラーで使用しました...

 IEnumerable<ClientViewModel> _clientVM = Mapper.Map<IEnumerable<Client>, IEnumerable<ClientViewModel>>(_clients);

以前に言及した質問に基づいて、すべてを設定したので使用できると思いましたが、コントローラーの上の行でエラーが発生しました...

「マッパーが初期化されていません。適切な構成でInitializeを呼び出します。コンテナなどを介してマッパーインスタンスを使用する場合は、静的なMapper.Mapメソッドを呼び出していないこと、ProjectToまたはUseAsDataSourceを使用していることを確認してください拡張メソッドの場合、適切なIConfigurationProviderインスタンスを必ず渡してください。」

私が見逃したもの..これはAutomapperをセットアップする正しい方法ですか?ここで一歩足りないと思います。

16
si2030

AutoMapperには、依存性注入と後方互換性のための古い静的の2つの使用法があります。依存性注入のために構成していますが、静的を使用しようとしています。それがあなたの問題です。いずれかの方法を選択して、それを選択するだけです。

依存性注入を使用する場合、コントローラーはマッパーをコンストラクター引数として受け取り、メンバーに保存する必要があります。その後、マッピングを行うにはそのメンバーを使用する必要があります。

public class FooController : Controller
{
    private readonly IMapper mapper;

    public FooController(IMapper mapper)
    {
        this.mapper = mapper;
    }

次に:

IEnumerable<ClientViewModel> _clientVM = mapper.Map<IEnumerable<Client>, IEnumerable<ClientViewModel>>(_clients);

静的メソッドの場合、設定でAutoMapperを初期化する必要があります。

public MapperConfiguration Configure()
{
    AutoMapper.Mapper.Initialize(cfg =>
    {
        cfg.AddProfile<ViewModelToDomainMappingProfile>();
        cfg.AddProfile<DomainToViewModelMappingProfile>();
        cfg.AddProfile<BiDirectionalViewModelDomain>();
    });
}

その後、Startup.csでこのメソッドを呼び出すだけです。シングルトンを登録しなくなります。

30
Chris Pratt

AutoMapper.Extensions.Microsfot.DependencyInjectionバージョン5.0.1およびAutoMapper 7.0.1でこのエラーが発生しています。 AutoMapper 6.1.1で3.2.0をインストールすると問題が修正され、_mapper.Mapを通常どおり呼び出します。静的なMapperクラスを呼び出しておらず、ProjectToまたはUseAsDataSourceを使用していないと判断できる限り、原因はわかりません。

0
MDave