Caliburn.Micro で構築された Silverlight 5.0 UI で構成される内部デモ用のコードをまとめています。
要約シナリオ: サービス プロキシ クラスからビュー モデルのリストをマップするために AutoMapper を取得しようとしています。ビュー モデルには ctor 依存関係があるため、Ninject を使用してこれを解決したいと考えています。
詳細: サービスを呼び出す親ビュー モデル (AvailableItemsViewModel) があります。次に、AutoMapper を使用して、返された DTO のリストを AvailableItemViewModel にマップします。
AvailableItemViewModel は、Caliburn の IEventAggregator への参照を受け取ります。これは、ビュー モデルがユーザー入力に基づいてイベントを発行するためです。
もう読んだ:
Ninject を使用して AutoMapper の依存関係を注入する
Ninject 2.0 で注入されるように Automapper を構成する方法は?
これらはすべてかなり似ているように見えます...だから、Bootstrapクラスで次のようになりました:
public class AutoMapperModule : NinjectModule
{
public override void Load()
{
Bind<ITypeMapFactory>().To<TypeMapFactory>();
foreach (var mapper in MapperRegistry.AllMappers())
Bind<IObjectMapper>().ToConstant(mapper);
Bind<ConfigurationStore>().ToSelf().InSingletonScope().WithConstructorArgument("mappers", ctx => ctx.Kernel.GetAll<IObjectMapper>());
Bind<IConfiguration>().ToMethod(ctx => ctx.Kernel.Get<ConfigurationStore>());
Bind<IConfigurationProvider>().ToMethod(ctx => ctx.Kernel.Get<ConfigurationStore>());
Bind<IMappingEngine>().To<MappingEngine>();
Mapper.Initialize(cfg =>
{
cfg.ConstructServicesUsing(t=>Kernel.Get(t));
});
}
}
ブートストラップにブレークポイントを設定すると、Ninject が AvailableItemViewModel のインスタンスを正常に作成できることがわかります。
エラーは次のとおりです。
{System.ArgumentException: Type 'Caliburn.Proto.ViewModels.AvailableItemViewModel' には System.Linq.Expressions.Expression.New(Type type) at AutoMapper.DelegateFactory.<>c__DisplayClass1.b__0(Type t) に既定のコンストラクターがありませんTvdP.Collections.ConcurrentDictionary2.GetOrAdd(TKey key, Func
2 valueFactory) で AutoMapper.DelegateFactory.CreateCtor(Type タイプ) で AutoMapper.Mappers.ObjectCreator.CreateObject(Type タイプ) で AutoMapper.MappingEngine.AutoMapper.IMappingEngineRunner.CreateObject(ResolutionContext コンテキスト) で AutoMapper.Mappers.TypeMapObjectMapperRegistry.NewObjectPropertyMapMappingStrategy.GetMappedObject( ResolutionContext コンテキスト、IMappingEngineRunner マッパー) で AutoMapper.Mappers.TypeMapObjectMapperRegistry.PropertyMapMappingStrategy.Map(ResolutionContext コンテキスト、IMappingEngineRunner マッパー) で AutoMapper.Mappers.TypeMapMapper.Map(ResolutionContext コンテキスト、IMappingEngineRunner マッパー) で AutoMapper.MappingEngine.AutoMapper.IMappingEngineRunner.Map(ResolutionContext環境)}
Ninjectは使用されていませんか?
マッピングを行うコードは次のとおりです。
var availItems = Mapper.Map<List<Item>, List<AvailableItemViewModel>>(shoppingListStore.GetAvailableItems().ToList());
AvailableItems = new ObservableCollection<AvailableItemViewModel>(availItems);
私は何が欠けていますか?
(AutoMapperはver2.1.267.0、Ninjectは3.0.0.0。Ninject.Conventionsも使っています)
[更新]投稿AutoMapper with Ninject の「回避策」も有効であることに注意してください。
[更新] これを考えると: Mapper.CreateMap().ConstructUsingServiceLocator();
ConstructUsingServiceLocator() メソッドを削除すると、Kernel.Get のブレークポイント:
cfg.ConstructServicesUsing(t=>Kernel.Get(t));
トリガーしません。両方が必要なようですか?