我正在为一个内部演示拼凑一些代码,该演示由基于 Caliburn.Micro 构建的 Silverlight 5.0 UI 组成。
摘要场景: 我试图让 AutoMapper 映射来自服务代理类的视图模型列表。视图模型具有 ctor 依赖关系,所以我想使用 Ninject 来解决这个问题。
详细信息: 我有一个调用服务的父视图模型 (AvailableItemsViewModel)。然后,它使用 AutoMapper 将返回的 DTO 列表映射到 AvailableItemViewModel。
AvailableItemViewModel 引用了 Caliburn 的 IEventAggregator - 因为视图模型将根据用户输入发布事件。
我读了:
如何配置 Automapper 以注入 Ninject 2.0?
所有这些看起来都非常相似......所以我在我的 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:类型“Caliburn.Proto.ViewModels.AvailableItemViewModel”在 AutoMapper.DelegateFactory 的 System.Linq.Expressions.Expression.New(Type type) 处没有默认构造函数。<>c__DisplayClass1.b__0(Type t) at TvdP.Collections.ConcurrentDictionary2.GetOrAdd(TKey key, Func
2 valueFactory) 在 AutoMapper.DelegateFactory.CreateCtor(Type type) 在 AutoMapper.Mappers.ObjectCreator.CreateObject(Type type) 在 AutoMapper.MappingEngine.AutoMapper.IMappingEngineRunner.CreateObject(ResolutionContext context) 在 AutoMapper.Mappers.TypeMapObjectMapperRegistry.NewObjectPropertyMappingStrategy.GetMappedObject( ResolutionContext context, IMappingEngineRunner mapper) at AutoMapper.Mappers.TypeMapObjectMapperRegistry.PropertyMappingStrategy.Map(ResolutionContext context, IMappingEngineRunner mapper) at AutoMapper.Mappers.TypeMapper.Map(ResolutionContext context, IMappingEngineRunner mapper) at AutoMapper.MappingEngine.AutoMapper.IMappingEngineRunner.Map(ResolutionContext语境)}
所以 Ninject 没有被使用?
进行映射的代码是:
var availItems = Mapper.Map<List<Item>, List<AvailableItemViewModel>>(shoppingListStore.GetAvailableItems().ToList());
AvailableItems = new ObservableCollection<AvailableItemViewModel>(availItems);
我错过了什么?
(AutoMapper 是 2.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));
不触发。所以看起来两者都是必需的?