Asp.net mvc 4 访问简单喷油器MVC视图的容器
在一个Sitecore项目中,我使用 它使用sitecore管道,然后使用App_start中的方法Asp.net mvc 4 访问简单喷油器MVC视图的容器,asp.net-mvc-4,dependency-injection,sitecore,inversion-of-control,simple-injector,Asp.net Mvc 4,Dependency Injection,Sitecore,Inversion Of Control,Simple Injector,在一个Sitecore项目中,我使用 它使用sitecore管道,然后使用App_start中的方法 namespace BBC.App_Start { public class SimpleInjector : IPackage { public void RegisterServices(Container container) { GetContainer.RegisterServices(container);
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);
}
}
}
简单地说,我可以将容器注入控制器构造函数,但不能在视图文件中包含容器
我试图在appstart中声明一个静态属性,并将容器保存到其中。但我仍然没有在视图中获得注册类型
在视图中使用容器对象的最佳方式是什么?正如他在评论中所建议的那样,您的问题的字面答案是“您不应该这样做,因为MVC和DI实际上不是这样工作的”。更详细的答案如下:
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);
}
}
视图的任务是显示通过模型传递的数据。视图不应该真正包含逻辑。非常简单的东西,如“如果标志为false,则隐藏此标记块”是可以的,但用于计算标志值的更复杂代码不应出现在视图中
MVC鼓励您将表示(视图)与数据(模型)和逻辑(控制器)分开,从而使我们的网站代码变得更好。这将使我们的代码更易于使用-因此,如果您有需要执行的处理,那么它应该在控制器方法运行时真正发生
如果视图需要一些特殊数据,最佳实践建议它应该在控制器方法中计算出来,并将其传递给模型中的视图。代码可能更像这样:
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);
}
}
然后,视图只需要接受MyModel
类作为其模型,并呈现SpecialData
属性-不需要逻辑
我认为,让调用从DI容器获取对象散布在代码库中也是一个坏主意。对于MVC应用程序,通常在应用程序启动时,DI容器会连接到为请求创建控制器的过程中。DI框架扩展了控制器的创建过程,而不是将DI容器传递到控制器中,并且容器不会暴露于此之外。当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框架可以将工厂对象传递给控制器,这将用于以后构建特殊对象
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的好书可能会建议其他更适合您特定问题的方法。您的视图中不应该有任何依赖项。视图应该是普通DTO,控制器(或其他组件)应该创建它们。也不应该将容器本身链接到类中;第三,你不应该注册(()=>newcontainer(),…)。这将注册一个空容器。