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

时间:2013-05-29 10:49:23

标签: c# asp.net-mvc asp.net-mvc-3

在我的mvc3控制器中,某个特定对象用于多种方法。我应该将它声明为控制器的成员变量并提供访问它的属性吗?但是每次从客户端调用一个action方法时会发生什么?是否会一次又一次地创建对象?如果是这种情况,上述方法有什么特别的优势吗? 将MySpclClass声明为单例类,在这种情况下是一个不错的选择吗?

简而言之,使用此方法是否有任何优势:

 public class MyController : Controller
    {
         MySpclClass myObject=new MySpclClass();


        public ActionResult DoFirst(int id)
        {
          ....................
          myObject.doOneThing();
          ....................  
        }

        public ActionResult DoSecond(int id)
        {
          ....................
          myObject.doAnotherthing();
          ....................  
        }
    }

这个方法:

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

编辑:将MySpclClass声明为单例类,这是Rajansoft1建议的一个很好的选择吗?需要有关此的建议。

7 个答案:

答案 0 :(得分:3)

除非您在一个请求中调用多个ActionResult方法,否则没有任何优势。

每个请求都会实例化Controller的 new 实例,因此无论如何都会在该点重新创建对象。

答案 1 :(得分:3)

您可以使用依赖注入来处理这些问题。 依赖注入的最佳工具之一是ninject,它创建一次对象的实例,并在任何控制器需要时提供它,你只需要配置一次。

如果你是ninject的新手,你可以在这里找到它 http://www.ninject.org/

答案 2 :(得分:2)

这就是你使用模型的原因。

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

答案 3 :(得分:1)

您的第二个选项(没有类级别字段)是最好的,因为它不会产生在请求之间保存字段值的印象(因为框架将为每个请求重新创建Controller实例)。< / p>

但是,如果在大多数方法中使用该字段,您可能会考虑使用该字段,但是您应该创建一个用于访问它的属性,以便在需要时自动实例化(或者始终在构造函数中实例化该字段)

private MySpclClass myObject;
public MySpclClass MyObject
{
    get
    {
        if (this.myObject == null)
            this.myObject = new MySplClass();
        return this.myObject;
    }
}

答案 4 :(得分:1)

如果您考虑控制器是按每个请求创建的,那么这一切都取决于您是否需要myobject来保留这些请求之间的某种状态。如果您只需要该对象的实例(具有默认状态),那么我会采用第一种方法,因为它比其他方法更干。

或者,如果myobject只是帮助者,您可以考虑将其设为static单身。

答案 5 :(得分:1)

每次调用一个动作方法时都会实例化控制器,所以在我看来你应该使用

public ActionResult DoFirst(int id) 
{
              MySpclClass myObject=new MySpclClass();
              myObject.doOneThing();
}

当变量的声明更接近使用时,它会更清楚。如果没有在所有动作方法中使用它,则无需实例化它。

答案 6 :(得分:0)

您可以使用以下代码

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