1

我正在为一个内部演示拼凑一些代码,该演示由基于 Caliburn.Micro 构建的 Silverlight 5.0 UI 组成。

摘要场景: 我试图让 AutoMapper 映射来自服务代理类的视图模型列表。视图模型具有 ctor 依赖关系,所以我想使用 Ninject 来解决这个问题。

详细信息: 我有一个调用服务的父视图模型 (AvailableItemsViewModel)。然后,它使用 AutoMapper 将返回的 DTO 列表映射到 AvailableItemViewModel。

AvailableItemViewModel 引用了 Caliburn 的 IEventAggregator - 因为视图模型将根据用户输入发布事件。

我读了:

使用 Ninject 注入 AutoMapper 依赖项

带有 Ninject 混淆的 AutoMapper

如何配置 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, Func2 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));

不触发。所以看起来两者都是必需的?

4

0 回答 0