The other day, I was writing some SharePoint code, and I required a RunWithElevatedPrivileges call. This call is normally accompanied by the creation of a new SPSite and a new SPWeb objects. This is even demonstrated in the RunWithElevatedPrivileges MSDN excerpt, as shown below. What this code does and such, it does not really matter for the sake of this post.
SPSecurity.RunWithElevatedPrivileges(delegate() { using (SPSite site = new SPSite(web.Site.ID)) { // implementation details omitted } });
This is all fine and good, but I’ve noticed that the project that I’m working on already contains loads of RunWithElevatedPrivileges and the accompanying creation of new SPSite and SPWeb; thus I thought that it would be great if I had access to an overload of RunWithElevatedPrivileges that provides a callback with SPSite and SPWeb as parameters rather than creating them myself. So I thought that this is probably offered by SharePoint but a quick look at the public SharePoint API shows that this does not exist.
Then I thought, how is this possible? This is a common use case; somewhere in the SharePoint API, this ought to exist. So, grabbing ILSpy, I’ve reflected the code and gave a quick look. Unsurprisingly, I’ve found the exact overload that I was looking for. Though, for some weird reason, it’s set to Internal, rather than public. Hold on a minute, why is this kind of API not public? This is not some kind of abstraction; it’s API that should be readily available for the developer.
// Microsoft.SharePoint.SPSecurity internal static void RunWithElevatedSiteAndWeb(SPWeb originalWeb, SPSecurity.CodeToRunWithElevatedSite secureCode) { if (originalWeb.CurrentUser != null && originalWeb.CurrentUser.ID == 1073741823 && !originalWeb.Site.HasAppPrincipalContext) { secureCode(originalWeb.Site, originalWeb); return; } SPSecurity.RunWithElevatedPrivileges(delegate { using (SPSite sPSite = new SPSite(originalWeb.Site.ID, originalWeb.Site.Zone)) { using (SPWeb sPWeb = sPSite.OpenWeb(originalWeb.ID)) { secureCode(sPSite, sPWeb); } } }); }
This made me think: can we be a bit more careful on how we use the Internal access modifier? I mean, I understand that portions of the code should be private, since such code will be only used in the same class to simplify the underlying code. But, API that are clearly useful by developers having a LOT of internal methods is a big no for me. It is clearly not adding business value to the API, just frustration to the end developer since he needs to re-implement (or copy) the same implementation in his solution.
Obviously, I am not saying that ALL Internal methods are badly designed; if this was the case, it would not exist at all. I’m saying that API developers should think twice before limiting API to internal, which can clearly be used 3rd party developers. Private methods are OK, but internal methods, I think one needs to be a bit more careful on how this is used.
Or..maybe this is just one of the many, many quirks of the SharePoint API.