2

在我的 mvc3 控制器中,一个特定的对象用于几种方法。我应该将它声明为控制器的成员变量并提供访问它的属性吗?但是每次从客户端调用其中一个操作方法时会发生什么?对象会被一次又一次地创建吗?如果是这种情况,上述方法有什么特别的优势吗? 在这种情况下,将 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 建议的一个不错的选择?需要这方面的建议。

4

7 回答 7

3

没有优势,除非您ActionResult在一个请求上调用多个方法。

每个请求都会实例化你的控制器的一个实例,所以无论如何你的对象都会在那个时候重新创建。

于 2013-05-29T10:53:08.100 回答
3

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

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

于 2013-05-29T10:53:12.410 回答
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);
    }
}
于 2013-05-29T10:59:27.700 回答
1

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

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

private MySpclClass myObject;
public MySpclClass MyObject
{
    get
    {
        if (this.myObject == null)
            this.myObject = new MySplClass();
        return this.myObject;
    }
}
于 2013-05-29T10:53:41.957 回答
1

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

或者,如果myobject只是一个助手,您可以考虑将其static设为单例。

于 2013-05-29T10:54:56.567 回答
1

每次调用动作方法时都会实例化控制器,因此我认为您应该使用

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

当变量的声明更接近用法时,它会更清楚。如果不是从所有操作方法中使用它,就没有实例化它的意义。

于 2013-05-29T10:57:54.323 回答
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
于 2013-05-29T12:25:37.007 回答