【问题标题】:instantiate SPSite and SPWeb objects实例化 SPSite 和 SPWeb 对象
【发布时间】:2010-01-25 08:41:45
【问题描述】:

我想知道实例化 SPSite 和 SPWeb 对象的最佳方法是什么。因为没有。您可以通过哪些方式做到这一点。我知道的一些方法

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

//为什么我们使用第二种方法和第一种方法一样,不需要编写硬编码的url,也不需要按照微软的建议进行处理。

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;

让我知道是否还有其他最好的方法或手段,这应该是实例化对象的最佳方法.....

谢谢,

【问题讨论】:

    标签: sharepoint


    【解决方案1】:

    你应该这样做:

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

    您还应该看看这个:SharePoint Dispose Checker Tool,因为它可以检查您的代码并指出您缺少最佳实践的地方。

    编辑:是的,您可以使用Context(我一直这样做),但在某些情况下不应该使用它,例如在SPSecurity.RunWithElevatedPrivileges 中。所以,我建议:

    • 1 正常操作的方法
    • 2 代表 RunWithElevatedPrivileges
    • 3 不应该被使用,因为它可能如果被处理掉会弄乱你的请求。

    【讨论】:

    • 感谢您的回复...但我的问题是哪个是实例化的最佳方法...您说通过 givig url 进行实例化但为什么我们不能使用 SPContext ...?
    • 好的...我也使用方法 1) 但我已经看到方法 2) 在网络和书籍中使用得更多,所以认为可能是 2) 是更好的方法。鲁本斯,没有必要在方法 1 中处理它)只有在您创建它时才进行仪式,因为我们在方法 2 中拥有它)
    • 我这里没有共享点框;您能否使用上述所有三种方法创建一个程序并运行该 SPDisposeChecker 工具?这与 Microsoft 最佳实践文档一致。
    • 您应该尽可能避免创建新的 SPSite 对象。即使你丢弃它们,它们也是“昂贵的”。
    【解决方案2】:

    基本上,创建一个 new SPSite 对象在所需的内存方面是“昂贵的”。这就是为什么您尽可能have to Dispose()他们 - 以释放您占用的资源。

    因此,只要此类方法可用,您就应该调用使用 SharePoint 中内置的“单例”的方法。例如,在您的第三个示例中,您调用 SPContext.Current.Web。在内部(如果您在 Reflector 中加载代码,您可以看到它)它存储对 SPWeb 对象的引用,并在您每次调用它时返回相同的对象。这意味着同一页面中的不同 Web 控件使用一个 SPSite 对象和一个 SPWeb 对象。但是,您的第二个示例创建了一个新的 SPSite 对象,这会占用您 2Mb 的内存(信息取自 Robert Lamb's article)。

    在我看来,第一种和第三种方法是等价的。其中一种方法在内部调用另一种方法(我目前无权访问 microsoft.sharepoint.dll,因此无法验证)。
    第二个例子不同。

    【讨论】:

    • 您是在暗示 SPSite 对象使用的内存量是应该处置它的原因。这不是真的。 Dispose 的原因是因为它们将 COM 对象保存在内存中,除非您调用 Dispose,否则这些对象不会被释放。 SPWeb 也是如此。
    • 这是一个有趣的细节点。有了无限的内存,就没有必要处理 COM 对象了。所以,可以说你们俩说的是同一件事。
    • @JD,我并不是说内存是您应该处理的唯一原因。但是,我仍然相信我们应该尽可能少地创建可以在我们自己的代码中创建的 SP.. 对象。由于内存使用我们不知道的其他资源。
    【解决方案3】:

    没有一种最好的方法,这取决于你在做什么。如果您正在编写您知道可以访问当前/隐式上下文(例如 Web 部件)的代码,则选项 #1 更可取。在当前上下文中,这种“背负式”速度更快,并且可以节省资源。 Rubens Farias 的帖子提供了一些有关限制的更多详细信息。

    有时您没有当前/隐式上下文,例如在命令行实用程序中。有时您想访问当前上下文之外的对象,例如在另一个 Web 应用程序中。在这些情况下,您只剩下选项 #2,它会启动自己的上下文。

    我倾向于将选项 #3 视为选项 #1 的冗余且表达较少的版本。其他人可能会提供一个令人信服的案例来使用它,但我没有遇到过。

    这两种方法(当前与显式上下文)都运行良好,应该在您的工具箱中。关键是了解在特定情况下为什么以及如何使用一种方法与另一种方法。

    【讨论】:

      【解决方案4】:

      方法 1 和 3 是等效的。事实上 SPContext (方法 3)正在使用方法 1 本身。 我更喜欢使用 SPContext.Current,因为当您还想使用 SPContect.Current.List 等时,它提供了很好的一致性,而 SPControl 不提供这种方式

      方法 2 适用于您不在相关站点内运行代码时使用,因此如果您正在创建控制台/WPF 应用程序或 stsadm 的扩展。

      如果您需要以提升的权限运行,则使用方法 2 的变体,以 Guid 和 SPUserToken 作为参数

      总而言之,我的建议是:如果可以使用方法 3,需要时使用方法 2

      【讨论】:

        猜你喜欢
        • 2014-02-18
        • 1970-01-01
        • 2015-10-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-04-26
        • 2019-12-28
        相关资源
        最近更新 更多