After reading some answers/comments on Disposal of SPWebs retrieved from SPContext.Current.Site.AllWebs, I opened up Reflector to dig deeper into the SPSite
and SPWeb
classes.
I ran into a surprise, which I thought would be worth sharing.
When looking at the implementation for SPSite.Dispose()
, which calls SPSite.Close()
, I found the following bit of code:
if (this.m_openedWebs != null)
{
List<SPWeb> list = new List<SPWeb>(this.m_openedWebs);
foreach (SPWeb web in list)
{
web.Close();
}
}
all SPWeb.Dispose()
does, is making a call to SPWeb.Close()
, making SPWeb.Close()
and SPWeb.Dispose()
functionally identical, so essentially when a SPSite
is disposed, all SPWebs
that appear in the this.m_openedWebs
collection are disposed along with it, right? Please correct me if I'm wrong!
At this point I was getting very curious as to how this collection was being populated. I found that when calling SPSite.OpenWeb(string)
, the new SPWeb
is actually added to this collection!
The following chain of methods will be called when calling SPSite.OpenWeb(string)
SPSite.OpenWeb(string) > SPSite.OpenWeb(string, bool) > new SPWeb(SPSite, string, bool) > SPWeb.SPWebConstructor(SPSite, string, bool, SPRequest) > SPSite.AddToOpenedWebs(SPWeb)
According to Roger Lamb, SPWebs
returned by SPSite.OpenWeb()
SHOULD be disposed (I am assuming this applies to all overloads for SPSite.OpenWeb()
), but based on my findings, I don't see why, as it seems to me that any SPWeb
opened using the SPSite.OpenWeb(string)
method is automatically disposed (closed) when the SPSite
on which OpenWeb()
was called is disposed.
I believe it's quite likely I have made some mistake in my thinking somewhere (who am I to question Roger Lamb?), but at this moment I don't know what to believe as I have two contradicting pieces of information.
What do you think?