【问题标题】:Subclassing SharePoint Objects子类化 SharePoint 对象
【发布时间】:2009-06-23 06:43:45
【问题描述】:

我想对一些 SharePoint 对象进行子类化,例如 SPSite、SPWeb、SPList 和 SPListItem。知道怎么做吗?我无法创建派生类的实例,因为我无法使用构造函数构造对象。

我通常使用容器类来包装上述对象,但我认为这不是一个好的解决方案,因为它没有为对象提供良好的语义和 OOP 感觉。感谢您提供任何帮助或建议。

谢谢。

【问题讨论】:

  • 您能用您想添加到子类的内容更新您的问题吗?从您的 cmets 到 kusek 的回答,您似乎想要标准的 SharePoint 对象和您的子类版本。为什么要这样做?
  • 嗨,Alex,这是正确的,我想派生标准 SharePoint 对象并将其扩展以添加我自己的方法和字段。例如,我有一个名为 Order 的自定义列表定义。而不是像这样的程序:SPListItem item = new SPListItem(); item["Title"] = "变形金刚 DVD";项目[“价格”] = 30.5;项目[“数量”] = 2;项目.更新(); OOP 方式应该这样完成: Order order = new Order("Transformers Movie", 30.5); order.SetQuantity(2); order.Save();类似的东西。
  • 对不起,格式有问题,我会在新的答案块中重新填写,请检查。

标签: sharepoint oop


【解决方案1】:

我建议不要对 SharePoint 对象进行子类化,因为我认为它没有任何用处。如果您要对 SharePoint 对象进行子类化只是为了添加或覆盖几个方法,请尝试使用 .NET 3.5 的扩展方法.这应该对你有帮助。

【讨论】:

  • (+1) 完全同意,不要去继承 SP API 对象,创建扩展方法或封装对象(不要忘记 Dispose!)
  • kusek 和 Colin,无论您建议不要对这些类进行子类化,我仍然愿意这样做,因为这是一种很好的 OOP 实践(而不是在表单中创建一堆辅助方法)静态或扩展方法,或者改为程序化)。由于您建议不要对它们进行子类化,我想您已经知道如何去做以及有什么限制。你介意分享给我吗?非常感谢。
  • 对这个产品要务实。您不能使用 SharePoint 进行“最佳 OOP 实践”。我不能足够强烈地说明这一点。
  • 就像 Nat 所说,Sharepoint 中发生了太多关于一次性物品等的废话,很难保持焦点。我做了一次 SPWeb 子类,只是为了让一些同事去修改它,忘记在覆盖的 Dispose 等中添加一些东西。我发现它是一场噩梦......
  • 我同意 Nat & Colin 的观点,事实上我从未见过任何人继承子类,我们在直接消费对象时对 SP 对象的处理有很多问题,然后考虑案例的子类。这个讨论朝着不同的方向发展,如果你看到目前为止的 cmets 都说不要子类 SP 对象,它不是反对 OOP,而是反对你在做 SharePoint 对象的子类时会得到的副作用。
【解决方案2】:

没错,我想派生标准 SharePoint 对象并将其扩展以添加我自己的方法和字段。例如,我有一个名为 Order 的自定义列表定义。而不是像这样的程序:

SPListItem item = new SPListItem();
item["Title"] = "Transformers DVD";
item["Price"] = 30.5;
item["Qty"] = 2;
item.Update();

The OOP-way should be done like this:
Order order = new Order("Transformers Movie", 30.5);
order.SetQuantity(2);
order.Save();

类似的东西。

【讨论】:

  • 下次不要添加答案,只需使用此信息编辑问题。
【解决方案3】:

好吧,我会查看类似于表中的行的 SPListItem,而不是实体。要将数据推送到数据库,我们将有一个数据库层来处理所有与数据库相关的东西,并且通过实体传递数据。上面的代码可以改写如下。

class Order{ 
    public int Price {get;set;};
    public int Qty {get;set;}; 
    public String ItemName {get;set;};}
class OrderHandler{
     Order m_Order=null;
    public OrderHandler(Order oEntity)
    {
          m_Order=oEntity;
    }

    public void Insert(){
       SPListItem item = new SPListItem();
       item["Title"] = m_Order.ItemName;
       item["Price"] = m_Order.Price.ToString();
       item["Qty"] = m_Order.Qty.ToString();
       item.Update();
    }
}

我很确定这并没有错。

【讨论】:

  • 其实这有问题。由于 Order 不是从 SPListItem 对象派生的,因此您必须重写所有属性以获取例如:order.ID、order.Title、order.Url。您将通过继承自动获取这些属性。
  • 好吧,让我换个问题,如果你已经将订单存储在 SQL 表中,你将如何处理它?
  • 我认为这个问题不相关。 SQL 表不提供任何对象供我派生。但 SharePoint 可以。我很欣赏你所有的回应,但请保持这个话题。我的问题是如何对 SharePoint 对象进行子类化。我不是问你为什么不应该。这应该是一个完全不同的讨论。谢谢。
【解决方案4】:

我同意其他发帖人的观点,即在 SharePoint 对象模型中对类型进行子分类是一个坏主意。我这样做的最大原因是:

  • SharePoint 本质上根据创建对象的上下文来处理对象的方式。
  • 您将基于不受您控制的子类型创建类型层次结构。

处置问题可能是最大的威慑。

继承并不总是坚持 OO 原则的最佳解决方案。在维护方面,对象层次结构也有其缺点。

听起来您已经探索过封装,这是一种完全有效的 OO 方法,并且比继承更受欢迎(在我看来):

public class Order {
    private SPListItem listItem;
    ...
    public Order(SPListItem listItem) {
        this.listItem = listItem;
    }

    ...

    public int ItemName {
        get { return listItem["Title"] as string }
        set { listItem["Title"] = value; }
    }
    ...
}

这些方法(继承和封装)的一个问题是它们将您的对象耦合到底层数据存储(在本例中为 SharePoint)。这可能是坏事,也可能不是坏事,具体取决于您要设计的内容。

另一种方法是将代码与底层存储区分开,并使用存储库来处理存储库中的对象获取和更新。至少任何与 SharePoint 的耦合都可以由单一存储库类型处理,并且您可以在其周围放置一个接口以允许您使用其他存储库(用于未来场景或测试)。

这完全取决于您的用例以及您的代码和平台将来可能会发生多少变化。

Chris O'Brien's blog (Simple data access pattern for SharePoint lists) 是一个不错的轻量级方法。如果您的需求与他的相匹配,这是一个实用的方法。

【讨论】:

  • 您好,dariom,感谢您的回复。但恐怕我不得不不同意你的观点。首先,在 MS 最佳实践文档中已经详细描述了在 SharePoint 中处理对象。无论您是否使用子类,作为 SharePoint 开发人员,您都必须仔细了解 dispose 模式。其次,使用 SharePoint(或一般的 .NET Framework),我们通常无法控制要派生的类型。例如,在创建自定义 Web 部件时,我们必须从 ASP.NET 或 SharePoint 继承 WebPart 类,这不是我们可以控制的。
  • 我以前看过 Chris O'Brien 的帖子,在某种程度上,我实际上一直在以类似的方式做事。我之前提到过,我一直在使用容器、存储库模式,甚至扩展方法。我正在寻找一种不同的方法来进行 SharePoint 编程,我认为继承和扩展 SharePoint 对象会非常有趣。就像任何一种方法一样,它有利也有弊。由于我还没有找到任何具体的方法(这是我未回答的问题),任何关于它的讨论都太假设了,我试图避免。
  • 嗨,丹妮。您关于无法控制基础类型的观点是正确的。至于处置:您班级的用户如何知道他们需要对调用 Dispose 应用与 SharePoint 所需的相同的规则?调用者是否真的必须知道您已对 SPWeb 进行了子类化并了解何时调用 Dispose?
  • 嗨,dariom,基本上应该适用相同的规则。即,从 SPContext 对象获得的那些不能手动释放。因此,它取决于我们获取对象时的上下文,是原始 SharePoint 对象还是派生对象。这不仅适用于 SharePoint 对象。每次我们创建一个实现 IDisposable 接口的类时,类设计器都必须将其传达给用户。当我们使用非托管资源时,这是无法避免的。此外,如有必要,我们还可以定义自定义 FXCop 规则来强制正确处置对象。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-16
  • 1970-01-01
  • 2016-06-13
相关资源
最近更新 更多