根据其他值获取对象实例,而不使用服务位置

发布于 2024-12-02 03:13:48 字数 931 浏览 0 评论 0原文

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

我正在使用一个名为 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());
    }

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

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

但是服务位置也是一种反模式,

关于如何解决这个问题有什么建议吗?

I am using a Unit of Work pattern in my mvc 3 app with Ninject. I have run into a problem where i'm having difficulty solving it without using new or service location of some kind.

I am using an abstract base model called MyModel which has 2 concrete subclasses MyModel1 and MyModel2. These need to get sent to the view based on a value set in the users record.

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

This works fine (although I don't like it, it's simple and works. The problem is that using new is an anti-pattern when using Dependancy Injection. Additionally, I now want the models to initialize themselves (from the database) so I need to inject the IUnitOfWork into the constructor of the models. I could, of course do this:

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

But Service Location is also an anti-pattern.

Any suggestions on how to solve this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

忆离笙 2024-12-09 03:13:48

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

但对于 MVC 应用程序来说,在视图模型中包含逻辑或数据检索代码是一种反模式,因此它们需要依赖项。所有这些东西都属于控制器或某些服务的外部。数据从外部被分配给视图模型。

Using new is not an anti pattern for DI if used correctly. There is absolutely no problem to use new to create data containers such as view models.

But it is an anti pattern for MVC applications to have logic or data retrieving code in your view models so that they need dependencies. All this stuff belongs outside into the controller or some services. The data is assigned preformatted to the view model from outside.

独夜无伴 2024-12-09 03:13:48

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

不。您不应将任何模型传递给您的视图。您仅通过“查看模型”。视图模型很愚蠢。它们仅包含供视图显示的预格式化数据。例如,如果您使用 AutoMapper 您可以将其外部化到映射层中,并且您的控制器可能会变成:

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

Additionally, I now want the models to initialize themselves (from the
database) so I need to inject the IUnitOfWork into the constructor of
the models

No. You should not pass any models to your views. You pass VIEW MODELS only. View models are dumb. They only contain preformatted data for the view to display. If you used AutoMapper for example you could have externalized this into the mapping layer and your controller could become:

public ActionResult MyMethod() {
    var user = _unitOfWork.Get(user)
    var userViewModel = Mapper.Map<User, UserViewModel>(user);
    return View(userViewModel);
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文