tags:

views:

202

answers:

4

Hi,

I want to know whats the best method of Instantiating SPSite and SPWeb objects . As there are no. of ways by which you can do this.Some of the ways I know

1. 
SPSite mySite = SPControl.GetContextSite(Context);
            SPWeb myWeb = SPControl.GetContextWeb(Context);

//Why we use second method as in first method there is no need to write the hardcoded url and also no need to dispose too as recommended by Microsoft.

2. 
SPSite mySite=new SPSite("http://abc");
SPWeb myweb= mySite.RootWeb;
//Dispose
mySite.Dispose();
myweb.Dispose();

  or difff. way of disposing for it by having using( )

/

   3. Similar to first.. SPSite mySite = SPContext.Current.Site;
                         SPWeb myweb = SPContext.Current.Web;

Let me know if there is any other best approach or means out of these which should be the best approach to instantiate objects.....

Thanks,

+3  A: 

You should do something like this:

using(SPSite oSPsite = new SPSite("http://server"))
{
    using(SPWeb oSPWeb = oSPSite.OpenWeb())
    {
        // do stuff
    }
} 

You should also take a look into this: SharePoint Dispose Checker Tool, as it can inspect your code and to point where you're missing best practices.

EDIT: Yes, you can to use Context (and it's way I always do) but it shouldn't be used in some scenarios, like inside a SPSecurity.RunWithElevatedPrivileges. So, I recommend:

  • 1 method for normal operations
  • 2 for RunWithElevatedPrivileges and
  • 3 should not be used, as it probably will mess your request if disposed.
Rubens Farias
Thanks for reply...but my question was which is the best method to instantiate...u said instantiating by givign url but why can't we use SPContext ...?
TSSS22
ok...I also use method 1) but I have seen method 2) used more in net and books so thought may be 2) is the better approach. Rubens, There is no need to dispose in method 1) rite its only when you are creating it as we have it in method 2)
TSSS22
I don't have a sharepoint box here; could you please create a program with all three approaches above and to run that SPDisposeChecker tool? That's aligned with Microsoft best practices documents.
Rubens Farias
You should avoid creating new SPSite objects whenever possible. Even if you dispose them, they are "expensive".
naivists
A: 

Hi ps123

Method 1 and 3 are equivalent. In fact SPContext (method 3) is using method 1 itself. I prefer to use SPContext.Current because it gives a nice consistency when you also want to use SPContect.Current.List and so on which isn't available from SPControl

Method 2 is for use when you're not running your code inside the site in question so if you're creating a console/WPF app or an extension to stsadm.

If you need to run with elevated privileges then use the variant of method 2 with Guid and SPUserToken as parameters

To sum it all up my recommendation is: Use method 3 if you can and method 2 when you need to

Per Jakobsen
A: 

Basically, creating a new SPSite object is "expensive" in terms of memory it requires. This is why you have to Dispose() them whenever you can - to free up resources you have taken.

So, whenever such method is available, you should call methods which use "singletons" built into SharePoint. For instance, in your 3rd example, you call SPContext.Current.Web. Internally (you can see it, if you load the code in Reflector) it stores a reference to the SPWeb object and returns you the same object, every time you call it. It means that different web controls in the same page use one single SPSite object and one SPWeb object. Your second example, however, creates a new SPSite object and that costs you 2Mb of memory (information taken from Robert Lamb's article).

In my opinion, the 1st and the 3rd method are equivalent. One of the methods calls the other one internally (I don't have access to microsoft.sharepoint.dll at the moment, so I cannot verify).
The 2nd example is different.

naivists
You are implying that the amount of memory used by a SPSite object is why it should be disposed. This is not true. The reason to Dispose is because they hold COM objects in memory that are not freed unless you call Dispose. Same thing is true with SPWeb.
JD
This is an interesting point of detail. With unlimited memory it wouldn't be necessary to dispose of COM objects. So, arguably you are both saying the same thing.
Jason Weber
@JD, I don't mean that memory is the *only* reason why you should dispose. But still, I believe we should create as few SP.. objects we can make in our own code as possible. Due to memory usage *and* other resources which we don't know of.
naivists
A: 

There is no one best way, it depends on what you're doing. If you're writing code where you know you have access to a current/implicit context such as a web part, option #1 is preferable. This "piggy backs" on the current context, is faster and saves resources. Rubens Farias' post offers some additional details regarding limitations.

Sometimes you don't have a current/implicit context such as in a command line utility. Sometimes you want to access objects outside of the current context such as in another web app. In these cases you are left with option #2 which spins up its own context.

I tend to view option #3 as a redundant and less expressive version of option #1. Someone else may be able to offer a compelling case for it's use but I have not run into it.

Both approaches (current vs. explicit context) work well and should be in your toolbox. The key is knowing why and how to employ one approach vs. another in a given situation.

Jason Weber