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建议的一个好选择?

MVC控制器:方法中的公共对象

除非在一个请求上调用多个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