访问Simple Injector MVC视图的容器

时间:2017-02-26 06:56:26

标签: asp.net-mvc-4 dependency-injection sitecore inversion-of-control simple-injector

在Sitecore项目中,我使用this article

集成了Simple Injector

它使用sitecore管道,然后在App_start中使用方法

namespace BBC.App_Start
{
    public class SimpleInjector : IPackage
    {
        public void RegisterServices(Container container)
        {
            GetContainer.RegisterServices(container);

            container.Register(() => new SitecoreContext(), Lifestyle.Scoped);
            container.Register(() => new Container(), Lifestyle.Singleton);
        }
    }
}

我可以将容器注入控制器构造函数,但在View文件中不能容器。

我尝试在App-start中声明一个静态属性并将容器保存到它。但我仍然没有在Views

中获得注册类型

在视图中拥有容器对象的最佳方法是什么?

1 个答案:

答案 0 :(得分:1)

正如Stephen在他的评论中所暗示的那样,你的问题的字面答案是“你不应该这样做 - 因为它不是MVC和DI应该工作的方式”。更详细的答案是这样的:

您的观点的工作是提供已通过模型传递的数据。视图不应该包含逻辑。非常简单的东西,比如“if flag is false,隐藏这个标记块”是可以的,但是更复杂的代码可以计算出标志的值不应该在视图中。

MVC尝试通过鼓励您将演示文稿(视图)与数据(模型)和逻辑(控制器<)分开来改善我们的网站代码/ em>的)。这应该使我们的代码更容易使用 - 所以如果你有需要处理的处理,那么当你的控制器方法运行时它应该真的发生。

如果您的视图需要一些特殊数据,最佳实践建议它应该在控制器方法中完成并将其传递给模型中的视图。代码可能看起来更像这样:

public class MyModel
{
    public string SpecialData { get; set; }
}

public class MyController : Controller
{
    public ActionResult DoSomething()
    {
        // do whatever processing is needed
        var somethingCalculate = resultFromYourOtherObject();
        // do other stuff

        var model = new MyModel() { SpecialData = somethingCalculated };

        return View(model);
    }
}

然后View只需接受MyModel类作为其模型,并呈现SpecialData属性 - 无需逻辑。

我认为从你的DI容器中获取对象的调用也是一个坏主意。对于MVC应用程序,通常您的DI容器会在应用程序启动时连接到为请求创建控制器的过程。 DI框架不是将DI容器传递给控制器​​,而是扩展了Controller创建过程,并且容器不会暴露在此之外。当MVC运行时需要创建控制器时,控制器创建逻辑使用DI框架来获取所有控制器依赖关系的对象。

如果没有关于实际想要实现的内容的更多细节,很难说这里创建对象的“正确”方法是什么,但两种最常见的模式可能是:

1)构造函数注入:您的控制器有一个接受所需对象的参数。 DI容器在创建控制器时为您创建此对象,因此控制器在创建时获取其所有依赖项。适用于:您知道如何在请求开始时创建对象的场景。

public interface IMySpecialObject
{
    string DoSomething();
}

public class MyController : Controller
{
    private IMySpecialObject _specialObject;

    public MyController(IMySpecialObject specialObject)
    {
        _specialObject = specialObject;
    }

    public ActionResult RenderAView()
    {
        // do some stuff
        var data = _specialObject.DoSomething();

        return View(data);
    }
}

只要IMySpecialObject及其具体实现在您的应用启动时在您的DI容器中注册,一切都很顺利。

2)工厂类但是,有时,相关对象可能是可选的,或者可能需要在控制器创建时不可用的数据来创建它。在这种情况下,您的DI框架可以将Factory对象传递给您的控制器,这用于稍后构建特殊对象。

public interface ISpecialFactory
{
    ISpecialObject CreateSpecialObject(object data);
}

public class MyController : Controller
{
    private IMySpecialFactory _specialFactory;

    public MyController(IMySpecialFactory specialFactory)
    {
        _specialFactory = specialFactory;
    }

    public ActionResult RenderAView()
    {
        // do some stuff
        if( requireSpecialObject )
        {
            var data = getSomeData();
            var specialObject = _specialFactory.CreateSpecialObject(data);
            var data = _specialObject.DoSomething();
            return View(data);
        }

        return View("someOtherView");
    }
}

但是一本关于使用DI的好书可能会提出更适合您特定问题的其他方法。