Design Patterns for developing SharePoint 2010 Solutions

Last week at the European SharePoint Conference, I talked about a few different design patterns that you can use when you develop custom solutions for SharePoint 2010, to make sure that your code is easy to maintain, extend and test.

We specifically talked about the following patterns:

• Repository
• Model-View-Presenter
• Service Locator

Each of these patterns offers a solution to different design issues that you might encounter when creating code based solutions. Our development team has successfully applied these patterns on several client projects where a fair amount of custom development was needed. However, applying the patterns will require some initial extra work and requires the developers in the team to be somewhat familiar with the patterns. So only apply them when you really see that you can get some benefit out of them.

Please check out the slides and sample code from the session.

To get started with the sample solution, please do the following:
• Download and unzip the package
• Open the SharePointEurope.DesignPatterns4 solution (the final solution where all patterns have been applied, as well as the configuration settings management)
• Deploy the SharePointEurope.Dependencies package to ensure that the common service locator library and application foundations are deployed to the GAC
• Create a site collection and deploy the SharePointEurope.DesignPatterns4 project to the site.
• Generate a Google Map Key for the host name of your web application and go to the configuration list (/Lists/Microsoft_Practices_SharePoint_ConfigList) and set this value.
• Create a few hotels in the Hotel list (/Lists/Hotels)
• Add the hotel finder web part somewhere and try it out

A few notes regarding the things we discussed at the session:

Repository implementation
There are many different ways to implement the repository pattern in SharePoint. In my sample implementation you have two options when creating the repository: Either provide the repository with a specific SPWeb object in the constructor, or use the context of the current web site. It’s important to make sure that you can use your repository from contexts where SPContext.Current is not available, such as i.e. timer jobs. Another option is to use configuration settings to provide an URL to a centrally located site where the hotels list is located – which is useful if you want to use the repository on other sites than where the list exists.

If you look at how the training management application in SharePoint Guidance 2007 is implemented, you can see that they use a slightly different approach. In that implementation, you need to provide the repository with an SPWeb object in each of the repositorys data access methods.

The problem with this approach is that your repository interfaces becomes cluttred with specific dependencies to SharePoint. An important goal of the repository pattern is that you should make yourself independent of exactly how the data is stored. And if you decide to change the data storage from SharePoint to i.e. SQL Server, you would need to not only change the implementation of the repository, but the interfaces and all the code that depends on it as well. In my opinion, it’s much better to let the repository get the data context it needs internally instead, or to use dependency injection to configure exactly how it’s provided to the repository. Here you could benefit quite a lot from using a proper dependency injection framework rather than the SharePoint Service Locator.

List based configuration
During the demo I showed you a simple example on how you could generate a configuration list and use it to store, retrieve and update settings. If you decide to go for the list based approach, I encourage you to check out the List Based Configuration Quickstart that’s available as a part of the SharePoint Guidance 2010 package. It’s a bit more refined and basically implements the same interfaces as the property bag-based configuration classes do. This makes it possible to use lists to store you configuration settings for any level of the farm (farm, web app, site collection or web) by specifying the path to a centrally located site collection where the settings are stored.

Using Application Foundations in sandboxed solutions
I got a few questions after the session about using the Application Foundations Library in sandboxed solutions.

The application settings manager can be used in sandboxed solutions, but there are a number of limitations of course. You can read more about using the application settings manager in sandboxed solutions here: http://msdn.microsoft.com/en-us/library/ff798449.aspx

I haven’t tried the SharePoint Service Locator in a sandboxed solution yet – if anyone has done that, I would be happy to hear about your experiences. Otherwise, there are plenty of other options for implementing the pattern, including implementing your own simple code-based service locator.

SharePoint 2010 Genesis Framework – A framework that will help you create amazingly structured SharePoint solutions

Summary: SharePoint 2010 Genesis Framework is a framework that helps you declare fields, content types, lists and feature definitions through code. It also helps with provisioning and stronly typed data access.

One of SharePoints greatest strengths is its flexibility. Power users can easily create very powerful solution without much involvement of developers. In many cases though, custom development is needed for parts of a solution. In those cases, it’s very important to properly package the code together with the storage structures such as site columns, content types, lists, views and so on into a solution package.

However, doing this the “classic” way – defining the storage elements with CAML can cause some challenges both during the development phase and when the solution goes to application management. Most developers struggle with the following challenges:

• A lot of CAML/XML needs to be written
• It’s difficult to handle additions and changes to content types already in use
• No strongly typed access to SharePoint Data, unless you choose use LINQ-2-SharePoint

The new upgrade actions in SharePoint 2010 helps somewhat, but when working in an agile manner with deployments every 2-3 weeks, the XML can get really messy.

What many developers do is to manage most of the provisioning of content types, site columns, etc. with code and “ensure-style-features” that incrementally update the content types, lists, views, etc. This requires quite a lot of coding though, and many developers create their own helper classes that quickly evolve into “mini-frameworks”.

Tony Restaino, a senior SharePoint developer at Avega has been working on this issue for a while and have recently released an extensive framework to solve this issue – SharePoint 2010 Genesis Framework (SPGEN).

Tony and I have been working for a client on a two large SharePoint projects for a while now, and we have been using this framework to define content types, site columns, features, etc. and all the provisioning and data access. Want to add a new field to a content type? No problem – just create the field as a class, add it to the content type, rebuild and deploy the code, reactivate the feature and it’s there! The framework has also helped us implementing the repositories with with strongly typed data access in no time!

It’s just amazing how easy life gets with solutions like these! If only Microsoft could be just as thoughtful as Tony when developing the SharePoint API 🙂

A few of the key features of SPGEN:

  • It allows you to create classes that represent the different kind of elements in SharePoint – Site Columns, Content Types, List Instances, Views, Features etc.
  • You set attributes on the classes that correspond to the attributes of the SharePoint XML elements. This gives you strongly typed access to the definitions at any time!
  • The framework provides a lot of helper methods to provision fields, lists, views, etc. It automatically takes care of incremental updates, such as adding a new field to a list.
  • It also provides a way to easily create ListItem–object field mappers that maps list items to any class – no need to use the nasty auto generated mega classes from SPMetal!  You can even create your custom field adapters if you have custom columns that maps to complex data types.
  • It provides data access methods that allows you to do both CAML and LINQ queries against the lists, and returns the result as strongly typed objects.
  • It provides a LINQ implementation that has a LOT better performance the LINQ-2-SharePoint (at least according to our own measurements).

As you can see, it’s a very competent framework that can save a you lot of work – especially when developing custom code-based solutions. I strongly encourage everyone to check it out and give it a try!

Read more and download the framework here:

http://spgenesis.codeplex.com/

LINQ to SharePoint is not a substitute for a repository

LINQ to SharePoint is a nice new feature of SharePoint 2010, which offer both strongly typed access to SharePoint list data, as well as translation between LINQ and CAML queries. Even though this makes data access against lists a lot easier than before, there are a few things to keep in mind before deciding to use this in your solution.

First of all, LINQ to SharePoint is NOT a substitute for a repository. The SPMetal objects that are returned from the LINQ queries are basically just strongly typed representations of the list item objects. If you need change the structure of your list, you will have to update the SPMetal classes which will cause problems of you have a lot of dependencies to these classes in your code. Using LINQ to SharePoint directly from your UI components can lead to just as unmaintainable solutions as those built on LINQ to SQL.

A lot better option (see the image on the right side) is to create your own domain classes, create a mapping between your domain class and SPMetal class and encapsulate this together with the data access code in a repository. If anything changes in the list item structure, you will only need to update the mapper and SPMetal classes, nothing else.

Also, be aware that using LINQ to SharePoint may cause a performance overhead. We have done some simple performance measurement where we compare data access through LINQ with ‘classic’ style SPQuery. SPQuery actually performs a lot better. Two possible reasons are overhead in query translation from LINQ to CAML and the mapping between SPListItem and SPMetal object. Since the overhead is just as big when executing queries that return zero items, the query parsing and translation is the most likely cause of the performance penalty.

Of course, you can also still build your repository in the same manner as SharePoint Guidance for SharePoint 2007, with your own List Item mappers and CAML queries embedded in the repository.

There are a few options here, which is probably the best argument for building a repository that returns instances of your own domain classes rather than the SPMetal generated classes. If you do that, you are free to change the internal implementation and storage model without impacting the rest of your solution.