在不使用服务位置的情况下,基于其他值获取对象实例

时间:2011-08-31 18:14:14

标签: c# asp.net-mvc-3 dependency-injection ninject-2

我在使用Ninject的mvc 3应用程序中使用了一个工作单元模式。我遇到了一个问题,我无法使用某种新的或服务位置来解决它。

我使用的是名为MyModel的抽象基础模型,它有2个具体的子类MyModel1MyModel2。这些需要根据用户记录中设置的值发送到视图。

public class MyController : Controller
{
    private IUnitOfWork _unitOfWork;
    public MyController(IUnitOfWork unitOfWork) { _unitOfWork = unitOfWork; }

    ...

    public ActionResult MyMethod() {
        var user = _unitOfWork.Get(user)

        if (user.myprop == somevalue)
        {
            return View(new MyModel1());
        }

        return View(new MyModel2());
    }

这很好用(虽然我不喜欢它,它很简单且有效。问题是在使用Dependancy Injection时使用new是一种反模式。另外,我现在希望模型自己初始化(从数据库中)所以我需要将IUnitOfWork注入到模型的构造函数中。我当然可以这样做:

if (user.myprop == somevalue)
{
    return View(DependancyResolver.Current.GetService(typeof(MyModel1)));
}

但服务地点也是一种反模式。

有关如何解决此问题的任何建议?

2 个答案:

答案 0 :(得分:3)

如果正确使用,使用new不是DI的反模式。使用new来创建数据容器(例如视图模型)绝对没有问题。

但是MVC应用程序的反模式是在视图模型中使用逻辑或数据检索代码,以便它们需要依赖项。所有这些东西都属于控制器或某些服务。数据从外部预先格式化为视图模型。

答案 1 :(得分:2)

  

此外,我现在希望模型自己初始化(来自   数据库)所以我需要将IUnitOfWork注入到构造函数中   模型

没有。您不应将任何模型传递给您的视图。您只通过VIEW MODELS。查看模型很愚蠢。它们仅包含要显示的视图的预格式化数据。例如,如果您使用AutoMapper,则可以将其外部化到映射层,您的控制器可能会变为:

public ActionResult MyMethod() {
    var user = _unitOfWork.Get(user)
    var userViewModel = Mapper.Map<User, UserViewModel>(user);
    return View(userViewModel);
}