SPWeb.Site, should you call Dispose() on it

disposesharepoint

Updated 06/08/2009 15:52: Short answer NO. Original question:

I can't find any reference which gives guidance on SPWeb.Site regarding disposing. I've gone through some of the more popular best practises documentation on disposing SharePoint objects:

Unfortunately none of these guidelines mention SPWeb.Site. To give some context, I'm writing a public extension API which accepts an SPWeb as an argument to a method i.e.:

public static void GetWebPartFromCatalog(this SPWeb web, string webPartName)
{
     ......

     SPSite site = web.Site;
     ......

     **OR** ??

     using (SPSite site = web.Site)
     {
         ....
     }
}

I've looked as the Close() method in refelector for SPWeb, which is called by SPWeb.Dispose() and there is nothing in it to indicate the actual SPSite member field is disposed of.

Update: 06/08/2009 13:47

At Alex's suggestion

"Put it in a loop which runs 100 times and use the SPRequestStackTrace registry key described in Troubleshooting SPSite/SPWeb leaks in WSS v3 and MOSS 2007 to check that your test code is the source of the problem."

I ran the following piece of code included inside a webpart:

 for (int i = 0; i < 100; i++)
 {
     using (SPWeb web = SPContext.Current.Site.OpenWeb(""))
     {
            SPSite site = web.Site;
            Debug.WriteLine(site.Url);
     }
 }

Nothing appeared in the SharePoint logs.

Whilst I would hesitate to make any real conclusions from this naive experiment, It would suggest that it's not necessary to dispose of SPWeb.Site. It would be really nice to get a concrete answer from someone more informed on this subject.

Update: 06/08/2009 14:52
Prompted by Greg's Comment I worked out the assignments of m_Site and it appears it's ultimately always passed into SPWeb via the internal constructors. E.g. SPWeb.OpenWeb passes in this to new SPWeb(). So I'm more sure that SPWeb.Site should not be disposed, indeed could cause problems if it was.

Best Solution

Kirk's answer is correct. You must have some handle to an SPSite before an SPWeb can be created, and that is the same SPSite instance you will have when you call SPWeb.Site.

Let's think through the implications of that - if you do not control the creation of the SPSite, but one of its child webs is handed to you from external code, and you dispose the site, when control is returned to the calling code, you've disposed a Site they may not be done with! Put yourself in the calling code's shoes: you pass an SPWeb into a method, and when that method is done, the SPSite you were using has been closed. It is always the instanciator's responsibility to clean up resources they allocate. Do not dispose the SPSite in this case.

Related Question