MVC控制器:方法中的公共对象
本文关键字:公共对象 方法 控制器 MVC | 更新日期: 2023-09-27 18:15:47
在我的mvc3控制器中,一个特定的对象在几个方法中使用。我是否应该将其声明为控制器的成员变量并提供属性来访问它?但是每次从客户机调用一个操作方法时会发生什么呢?对象会被一次又一次地创建吗?如果是这样的话,上述方法有什么特别的优点吗?是否声明MySpclClass为单例类,在这种情况下是一个很好的选择?
总之,使用这种方法有什么优点吗?
public class MyController : Controller
{
MySpclClass myObject=new MySpclClass();
public ActionResult DoFirst(int id)
{
....................
myObject.doOneThing();
....................
}
public ActionResult DoSecond(int id)
{
....................
myObject.doAnotherthing();
....................
}
}
over this method:
public class MyController : Controller
{
public ActionResult DoFirst(int id)
{
MySpclClass myObject=new MySpclClass();
....................
myObject.doOneThing();
....................
}
public ActionResult DoSecond(int id)
{
MySpclClass myObject=new MySpclClass();
....................
myObject.doAnotherthing();
....................
}
}
那这个呢:
public class MyController : Controller
{
MySpclClass myObject;
public ActionResult DoFirst(int id)
{
myObject=new MySpclClass();
....................
myObject.doOneThing();
....................
}
public ActionResult DoSecond(int id)
{
myObject=new MySpclClass();
....................
myObject.doAnotherthing();
....................
}
}
EDIT:是否将MySpclClass声明为单例类,在这种情况下如rajansof1建议的一个好选择?
除非在一个请求上调用多个ActionResult
方法,否则没有任何优势。
每个请求都将实例化一个新的 Controller实例,所以无论如何你的对象将在那个点被重新创建。
您可以使用依赖注入来处理这些问题。ninject是最好的依赖注入工具之一,它只创建一个对象的实例,并在任何控制器中需要它时提供它,你只需要配置它一次。
如果你不熟悉ninject,你可以在这里找到它http://www.ninject.org/
这就是你使用模型的原因。
public class MyController : Controller
{
public ActionResult DoFirst(int id)
{
MySpclClass myObject = new MySpclClass(); // The model
myObject.doOneThing(); // Set some properties on the model that are stored on the view as hiddenfields and will be posted back to the "DoSecond" action.
return view("MyView", myObject);
}
[HttpPost]
public ActionResult DoSecond(MySpclClass myObject)
{
myObject.doAnotherthing(); // Uses the properties that where stored on the view and posted back again.
return view("MyView", myObject);
}
}
第二个选项(没有类级别字段)是最好的,因为它不会产生字段值在请求之间保存的印象(因为框架将为每个请求重新创建Controller实例)。
然而,如果这个字段在你的大多数方法中使用,你可能会考虑使用这个字段,但是你应该像这样创建一个属性来访问它,这样它就会在需要的时候自动实例化(或者总是在构造函数中实例化这个字段)。
private MySpclClass myObject;
public MySpclClass MyObject
{
get
{
if (this.myObject == null)
this.myObject = new MySplClass();
return this.myObject;
}
}
每次操作方法被调用时控制器都会被实例化,所以我认为你应该使用
public ActionResult DoFirst(int id)
{
MySpclClass myObject=new MySpclClass();
myObject.doOneThing();
}
当变量的声明更接近用法时,它使它更清楚。如果没有在所有的动作方法中使用它,那么实例化它就没有意义了。
如果您考虑到每个请求都创建了控制器,那么这一切都取决于您是否需要myobject
在这些请求中保留某种状态。如果您只需要该对象的实例(具有默认状态),那么我会使用第一种方法,因为它比其他方法更DRY。
或者,如果myobject
只是一个助手,您可以考虑使其成为static
单例。
可以使用下面的代码
public class MyController : Controller
{
private readonly IMySpclClass _mySpclClass;
public void MyController(IMySpclClass mySpclClass)
{
_mySpclClass = mySpclClass;
}
public ActionResult DoFirst(int id)
{
_myObject.doOneThing(); // Set some properties on the model that are stored on the view as hiddenfields and will be posted back to the "DoSecond" action.
return view("MyView", myObject);
}
[HttpPost]
public ActionResult DoSecond(MySpclClass myObject)
{
_myObject.doAnotherthing(); // Uses the properties that where stored on the view and posted back again.
return view("MyView", myObject);
}
}
//and add the below code to ninject factor class
_kernel.Bind<IMySpclClass >().To<MySpclClass >().InSingletonScope();
//also intialize _kernel above as shown
private static IKernel _kernel;
public static void Register()
{
_kernel = new StandardKernel();
AddBindings();
}
private static IKernel Instance
{
get { return _kernel; }
}
and write all the bindings in the AddBindings() function