【问题标题】:Resolve Array with Ninject使用 Ninject 解析数组
【发布时间】:2010-08-25 03:50:52
【问题描述】:

在 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/ 或@ 987654322@)。不同之处在于,在使用 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
}

这里是我的 AutoMapViewResult:

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) 的包装器

【问题讨论】:

  • 首先,您告诉我们的错误信息比“不起作用”更多。
  • @Timwi:很抱歉在这里不清楚。我不是说,这段代码不起作用,而是这段代码不打算起作用。我编辑了我的问题,以更清楚地说明我要做什么。 @Ruben:我已经阅读了您对这个问题的回答,但我不确定它是否真的相同。一个区别是,当我尝试使用自动隐式自绑定来实现这一点时,存在显式绑定

标签: c# asp.net-mvc arrays ninject automapper


【解决方案1】:

猜测:你的意思是改写这个吗?

Foo foo = Kernel.Get<Foo>();

Foo[] foos = Kernel.Get<Foo[]>();

【讨论】:

  • 我需要使用非泛型 Get 函数,因为在编译时类型未知。看看我编辑的问题。
【解决方案2】:

好的,最后我为我的 AutoMapViewResult 找到了一些解决方法。它有效,但对我来说似乎有点像黑客......但是,它是:

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>());
        }
    }
}

通用参数TSourceTDestination 总是描述单个对象,而不是数组。所以要映射一个数组,这是使用它的代码:

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

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

【讨论】:

  • 请注意:考虑到这一点,我问自己,如果我不指定它的长度,IoC 容器是否有可能返回一个数组......
猜你喜欢
  • 2016-02-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多