代码之家  ›  专栏  ›  技术社区  ›  davehauser

用Ninject解析数组

  •  1
  • davehauser  · 技术社区  · 16 年前

    在Ninject中,对于具体类型有自动隐式自绑定。因此,无需进一步配置,我就可以解析应用程序中的每种类型,如:

    Foo foo = Kernel.Get(typeof(Foo));
    

    现在如果我需要一组 Foo ,我该怎么做?

    Foo[] foos = Kernel.Get(typeof(Foo[])); // does not work
    

    编辑:

    为了澄清,这里是,我实际上想要达到的:在一个ASP.NET MVC应用程序我有一个AutoMapViewResult(就像Jimmy Bogard在这个伟大的(!)视频: http://www.viddler.com/explore/mvcconf/videos/1/ 或在 ASP.NET MVC 2 in Action ). 不同之处在于,在使用AutoMapper将实体映射到视图模型之前,我需要向视图模型的构造函数注入一些服务。如果源类型是数组,我还必须实例化视图模型的数组。

    最后这里是一些(简化的)代码:-)

    public class EventsEditModel
    {
        // some properties here
        public Location[] Locations { get; set; }
        public EventsEditModel(ILocationService locationService)
        {
            Locations = locationService.GetAll().ToArray();
        }
    }
    public class EventsListModel
    {
        // some properties here
    }
    

    这是我的结果:

    public class AutoMapViewResult : ViewResult
    {
        public AutoMapViewResult(object model, Type sourceType, Type destinationType)
        {
            if (model != null)
            {
                var viewModel = IoC.Resolve(destinationType);
                ViewData.Model = Mapper.Map(model, viewModel, sourceType, destinationType);
            }
        }
    }
    

    EventsEditModel . 我的索引视图需要 EventsListModel[] System.ArgumentNullException :值不能为空。参数名称:source(在行中) var viewModel = IoC... )

    注: IoC.Resolve(Type serviceType) 只是包装纸而已 Kernel.Get(Type serviceType)

    2 回复  |  直到 16 年前
        1
  •  0
  •   Ruben Bartelink    16 年前

    猜猜:你是不是想写这个?

    Foo foo = Kernel.Get<Foo>();
    
    Foo[] foos = Kernel.Get<Foo[]>();
    
        2
  •  0
  •   davehauser    16 年前

    好的,最后我找到了一些解决方法。它的工作,但似乎有点像黑客对我来说。。。然而,这里是:

    public class AutoMapViewResult<TSource, TDestination> : ViewResult
    {
        public AutoMapViewResult(string viewName, string masterName, object model)
        {
            ViewName = viewName;
            MasterName = masterName;
    
            if (model.GetType().IsArray)
            {
                var viewModel = new List<TDestination>();
                foreach (var item in (TSource[])model)
                {
                    viewModel.Add(Mapper.Map<TSource, TDestination>((TSource)item, IoC.Resolve<TDestination>()));
                }
                ViewData.Model = viewModel.ToArray();
            }
            else if (model.GetType().IsGenericType)
            {
                var viewModel = new List<TDestination>();
                foreach (var item in (IEnumerable<TSource>)model)
                {
                    viewModel.Add(Mapper.Map<TSource, TDestination>((TSource)item, IoC.Resolve<TDestination>()));
                }
                ViewData.Model = viewModel;
            }
            else
            {
                ViewData.Model = Mapper.Map<TSource, TDestination>((TSource)model, IoC.Resolve<TDestination>());
            }
        }
    }
    

    泛型参数 TSource 和 TDestination 总是描述sinlge对象,而不是数组。所以要映射一个数组,下面是使用它的代码:

    public ActionResult Index()
    {
        var list = orderRepository.GetAll();
        return new AutoMapViewResult<Order, OrdersListModel>(null, null, list)
    }
    

    然后,AutoMapViewResult检查传递给构造函数的模型是否是数组或泛型列表,并构建它。