モデルをビューモデルに、またはその逆にマッピングするためにAutoMapperを使用するASP.NET MVC 5アプリケーションでNinjectを使用しようとしています。残念ながら、タイプマップの設定がないことを示すエラーメッセージが表示されます。
Ninject依存関係リゾルバーを作成しました。
namespace MyNamespace.Infrastructure
{
public class NinjectDependencyResolver: IDependencyResolver
{
private IKernel kernel;
public NinjectDependencyResolver(IKernel kernelParam)
{
kernel = kernelParam;
AddBindings();
}
public object GetService(Type serviceType)
{
return kernel.TryGet(serviceType);
}
public IEnumerable<object> GetServices(Type serviceType)
{
return kernel.GetAll(serviceType);
}
private void AddBindings()
{
kernel.Bind<IMyBLL>().To<MyBLL>();
}
}
}
これを使用してコントローラーを作成します。
namespace MyNamespace.Controllers
{
[Authorize]
public class HomeController : Controller
{
private IMyBLL _myBLL;
public HomeController(IMyBLL myBLLParam)
{
_myBLL = myBLLParam;
}
public PartialViewResult AddRecord()
{
return PartialView(new AddRecordViewModel());
}
[HttpPost]
public void AddRecord(AddRecordViewModel recordViewModel)
{
var record = Mapper.Map<Record>(recordViewModel);
_myBLL.AddRecord(record, User.Identity.Name);
}
}
}
Global.asax:
namespace MyNamespace.WebApplication
{
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
ApplicationUserManager.StartupAsync();
AreaRegistration.RegisterAllAreas();
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
AutoMapperWebConfiguration.Configure();
}
}
}
これはAutoMapper設定を呼び出します:
namespace MyNamespace.WebApplication.Infrastructure
{
public static class AutoMapperWebConfiguration
{
public static void Configure()
{
Mapper.Initialize(cfg => cfg.AddProfile(new RecordProfile()));
}
}
public class RecordProfile : Profile
{
protected override void Configure()
{
Mapper.CreateMap<AddRecordViewModel, Record>().ReverseMap();
}
}
}
これを実行すると、次のエラーメッセージが表示されます。
Missing type map configuration or unsupported mapping.
Mapping types:
AddRecordViewModel -> Record
MyNamespace.WebApplication.ViewModels.Home.AddRecordViewModel -> MyNamespace.Model.Record
Destination path:
Record
Source value:
MyNamespace.WebApplication.ViewModels.Home.AddRecordViewModel
何かが恋しいですか。 Ninject依存関係リゾルバーを使用する前に、問題なく機能しました。今では、マッピングが見つからないようです。
マッピング作成をコントローラーメソッドに直接追加すると、動作します:
[HttpPost]
public void AddRecord(AddRecordViewModel recordViewModel)
{
Mapper.CreateMap<AddRecordViewModel, Record>().ReverseMap();
var record = Mapper.Map<Record>(recordViewModel);
_myBLL.AddRecord(record, User.Identity.Name);
}
マッピング自体とモデルおよびビューモデルは問題ではないようです。どういうわけか、プログラムはマッピングを見つけられないと思います。
コントローラーメソッドでAuto Mapper Web Configurationを呼び出しても動作します:
public void AddRecord(AddRecordViewModel recordViewModel)
{
Infrastructure.AutoMapperWebConfiguration.Configure();
var record = Mapper.Map<Record>(recordViewModel);
_myBLL.AddRecord(record, User.Identity.Name);
}
逆マッピングも追加する必要があります。次の2つの方法のいずれかで実行できます。
Mapper.CreateMap<AddRecordViewModel, Record>();
Mapper.CreateMap<Record, AddRecordViewModel>();
または、次のようにします。
Mapper.CreateMap<AddRecordViewModel, Record>().ReverseMap();
あなたは私に尋ねる場合、後者が好ましいです。
プロファイルでMapper.CreateMapを呼び出さないでください。 base.CreateMapを呼び出すと、設定が完了します。
public class RecordProfile : Profile
{
protected override void Configure()
{
base.CreateMap<AddRecordViewModel, Record>().ReverseMap();
}
}
Mapper.Initialize()
は厳密に使用する必要がありますonceソリューションごと。
Initialize()
を後で呼び出した場合、以前のすべてのマッピングがオーバーライドされます。コードを注意深く調べて、このメソッドの呼び出しが別の場所で見つかると思います。
P.S .: 3年以上前にGitHubで作成されたコードの一部に見られるように、それはAutomapperの初期の動作ではありませんでした。
同様の問題がありました。Global.asaxに登録するのを忘れました
public class WebApiApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
AutoMapperConfig.RegisterMappings();
}
}
私の場合、問題は、デフォルトのAutomapperマッピングがIoCに登録されていることでした。
builder.Register(_ => AutomapperConfiguration.Configure()).As<IMapper>().SingleInstance();
失敗していたマッピングは、別の場所、サービス構成に登録されました
static void Main(string[] args)
{
var container = ConfigureDependencies();
AutoMapping.Configure();
プロジェクトでこのエラーが発生していたのは、サービス構成が実行されなかったテストプロジェクトでした。デバッグすると、IoCマッピングからのものを見ることができるように、失敗したマッピングが登録されたような錯覚を持っていました。
解決策、すべてのマッピングがテストソリューションに登録されていることを確認してください。