tags:

views:

230

answers:

4

Hi,

I want to subclass some SharePoint objects, such as SPSite, SPWeb, SPList, and SPListItem. Any idea how to do it? I cannot create an instance of my derived class since I can't construct the objects with a constructor.

I usually used a container class to wrap the said objects, but I don't think it's a good solution since it doesn't provide a good semantic and OOP-feel to the objects. Any help or suggestion are appreciated.

Thanks.

+8  A: 

I recommend not to subclass the SharePoint objects, as I don't see any use for it.If you are going to subclass the SharePoint objects just to add or override couple of methods, try using the Extension Methods of .NET 3.5. That should help you.

Kusek
(+1) Totally agree, don't go about subclassing SP API objects, create extension methods or encapsulate the objects (Don't forget to Dispose!)
Colin
Yepp, exactly what I´ve done...works great for implementing stuff that you wish you had on SPWeb but you don´t. Maybe a wiki post fo great extension methods for SharePoint would be something?
Johan Leino
@Johan, check out http://spexlib.codeplex.com
Alex Angas
Hi kusek,Thanks for the response.Thanks for your response. I actually have used the extension methods to do the same before. But it made a lot of confusions to other developers since the extension methods will be available in all SPSite/SPWeb/SPList/SPListItem instances. For example, in one class the SPWeb object has extra members (due to the inclusion of extension methods). Since the signature is still the same (SPWeb), it caused confusion. And we already know that extension and static methods, though helpful, are not a good OOP practice. So I abandoned it.
denni
kusek and Colin, regardless of your recommendation of not to subclassing those classes, I'd still like to do it since it is a good OOP practice (rather than creating a bunch of helper methods in the form of static or extension methods, or going procedural instead).Since you recommend not to subclass them, I guess you already know how to do it and what are the limitations. Do you mind sharing it to me? Many thanks.
denni
Be pragmatic with this product. You cannot do "best OOP practice" with SharePoint. I cannot state this strongly enough.
Nat
Like Nat says, there's just so much crap going on in Sharepoint with disposable objects etc, it's hard to keep the focus. I made an SPWeb subclas once, only for some colleague to go and modify it, forget to add some stuff to the overridden Dispose etc. I found it a nightmare...
Colin
Kusek
Hi Colin, since you said you already made an SPWeb sub class once, would you mind sharing how to do it? The farthest I can do is subclassing the SPSite object. Don't worry, I won't modify your subclass and cause you nightmare :)
denni
A: 

Hi Alex, that's correct, I want to derive the standard SharePoint objects and extend it to add my own methods and fields. For example, I have a custom list definition called Order. Instead of doing procedural like:

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();

Something like that.

denni
Next time rather than adding an answer, just edit the question with this information.
Alex Angas
Thanks for reminding, by the way, do you have any answer?
denni
A: 

Well I would view the SPListItem similar to the Row in a Table, than an Entity. To push a data to DB we will have a DB layer that handles all the DB related Stuffs and Passing data happens through Entities. Above code can be rewritten as below.

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();
    }
}

I am quite sure that there is nothing wrong in this.

Kusek
Actually there's something wrong with that. Since Order is not derived from the SPListItem object, then you have to rewrite all the properties to get for example: order.ID, order.Title, order.Url. You will automatically get those properties with inheritance.
denni
Okay let me put the question otherway, if you have stored the Order in the SQL table how would you handle it ?
Kusek
I don't find the question is relevant. SQL Table don't provide any object for me to derive. But SharePoint does.I'm appreciating all your responds, but please keep this on topic. My question is how to subclass a SharePoint object. I'm not asking why you shouldn't. It should be an entirely different discussion.Thanks.
denni
A: 

I agree with the sentiments of other posters that sub-classing the types in the SharePoint object model is a bad idea. My biggest reasons for doing so are:

  • the way that SharePoint intrinsically disposes objects based on the context they were created in.
  • you'd be creating a type hierarchy based on subtypes that aren't under your control.

The dispose issue is probably the biggest deterrent.

Inheritance isn't always the best solution in sticking to OO principles. An object hierarchy has it's downsides too when it comes to maintenance.

It sounds like you've already explored encapsulation which is a perfectly valid OO approach and would be preferred over inheritance (in my opinion):

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; }
    }
    ...
}

One problem with these approaches (inheritance and encapsulation) is that they couple your objects to the underlying data store (SharePoint in this case). This may or may not be a bad thing depending on what you're trying to design.

An alternative approach is keeping your code separate from the underlying store and using a repository to handle getting and updating objects in the repository. At least any coupling to SharePoint can be handled by a single repository type, and you can put an interface around it to allow you to use other repositories (either for future scenarios or for testing).

It all depends on your use case and how much your code and platform may change in the future.

One nice, lightweight approach is in Chris O'Brien's blog (Simple data access pattern for SharePoint lists). If your needs match up with his it's a practical way to go.

dariom
Hi dariom,Thanks for the response. But I'm afraid I have to disagree with your points. First, disposing objects in SharePoint is already described thoroughly in MS best practices documents. Whether or not you are using subclasses, as a SharePoint developer, you have to carefully learn about the dispose pattern. Second, with SharePoint (or .NET Framework in general), we usually don't have control on the types we want to derive. For example, when creating a custom Web part, we have to inherit the WebPart class from ASP.NET or SharePoint, which is not ours to control.
denni
I've come across Chris O'Brien's post before, and to some degree, I've actually been doing things in a similar way. I mentioned earlier, I've been there with containers, repository pattern, and even extension methods. I'm looking for a different approach on how to do SharePoint programming, and I think inheriting and extending SharePoint objects will be very interesting. Just like any kind of approach, it will have pros and cons. Since I haven't found any concrete way on how to do it (which is my unanswered question), any discussion about it will be too hypothetical, which I'm trying to avoid.
denni
Hi denni. Your point about not having control over the underlying type is valid. As for disposing: how will a user of your class know that they need to apply the same rules to calling Dispose as they need to for SharePoint? Should a caller really have to know that you've sub-classed SPWeb and understand when to call Dispose?
dariom
Hi dariom, basically the same rule should apply. I.e., the ones obtained from the SPContext object must not be disposed manually. So it depends on the context when we obtain the object, be it an original SharePoint object or a derived object. This doesn't apply only to SharePoint objects. Everytime we create a class that implement the IDisposable interface, the class designer has to communicate that to the user. This can't be avoided when we work with unmanaged resources. Also, if necessary, we can also define a custom FXCop rule to enforce the objects to be disposed properly.
denni