Bugfree.dk – Ronnie Holm's blog

Not anti-anything, just pro-quality

Unit testing LINQ to SQL using TypeMock

Posted by Ronnie Holm on May 4th, 2010

Recent months have brought about a proliferation of mocking frameworks that mocks what more traditional framework like Rhino Mocks cannot. Instead of creating and loading a mock implementation at runtime, the new breed of mocking frameworks hooks into the CLR to intercept and redirect calls. This opens up virtually every aspect of a class to mocking, which is useful for testing code not written with explicit testability in mind. Until recently, TypeMock was the only mocking framework around that took the latter approach, but it’s now being challenged by Moles from Microsoft Research and JustMock from Telerik.

Why traditional dependency-breaking techniques come short

After watching a screencast on how to use Moles to unit test LINQ to SQL without hitting the database, I thought it would be interesting to do the same with TypeMock. But first, let’s make sure we understand why traditional dependency-breaking techniques come short in testing LINQ to SQL. Assuming we want to put a repository under test, our goal is to mock how it accesses the database. Here’s a simple implementation of a repository that queries the Employee table of the AdventureWorks database:

    public class EmployeeRepository {
        public List<Employee> GetEmployeesByHireDate(DateTime start, DateTime end) {
            using (var ctx = new AdventureWorksDataContext())
                return (from e in ctx.Employees
                        where e.HireDate >= start && e.HireDate <= end
                        select e).ToList();
        }
    }

All calls to the database are routed through the AdventureWorksDataContext generated by Visual Studio. To mock access to the database, we therefore have to mock part of the data context. Easier said than done, though, for the context doesn’t expose an interface that a fake can implement. In addition, the tables are accessed through properties on the context that return a type of Table<TEntity>. Unfortunately, the constructor of Table<TEntity> is internal and the class itself is sealed, eliminating the hope of instantiating or subclassing the type by traditional means:

    public sealed class Table<TEntity> : IQueryProvider,
            ITable, IListSource, ITable<TEntity>, IQueryable<TEntity>,
            IEnumerable<TEntity>, IQueryable, IEnumerable
            where TEntity : class {
        internal Table(DataContext context, MetaTable metaTable) {
            ...
        }
    }

For an example of how the data context itself creates an instance of Table<TEntity>, take a look at the Employees property on the AdventureWorksDataContext. It relies on the GetTable<Employee> method on the DataContext class to create an instance of Table<Employee>. Despite its constructors being internal, the GetTable<TEntity> method has no trouble constructing an instance of the Table<TEntity> type, as they both reside in the System.Data.Linq assembly:

    public partial class AdventureWorksDataContext : DataContext {
        public Table<Employee> Employees {
            get {
                return GetTable<Employee>();
            }
        }
    }

How to break the unbreakable

The design of LINQ to SQL leaves us short of a traditional testing seam, as Michael Feathers would phrase it; a place at which we can alter the behavior of a program without editing in that place. This explains why, with LINQ to SQL, traditionally we’ve had to test against a real database with all its constraints, making our tests brittle, slow, and painful to write and maintain. With the new breed of mocking frameworks the issues of not being able to subclass or not being able to call an internal constructor go away (and new issues take their place). Regardless, here’s how to write a unit test for the CustomerRepository that doesn’t hit the database:

    [TestClass]
    public class CustomerRepositoryTest {
        private EmployeeRepository _repository;

        [TestInitialize]
        public void Initialize() {
            _repository = new EmployeeRepository();

            var fakeEmployees = new List<Employee> {
                new Employee {EmployeeID = 1, HireDate = new DateTime(2004, 12, 1)},
                new Employee {EmployeeID = 2, HireDate = new DateTime(2006, 7, 1)},
                new Employee {EmployeeID = 3, HireDate = new DateTime(2009, 3, 1)}
            }.AsQueryable();

            var fakeDataContext = Isolate.Fake.Instance<AdventureWorksDataContext>();
            Isolate.Swap.NextInstance<AdventureWorksDataContext>().With(fakeDataContext);

            // var fakeEmployeeTable = Isolate.Fake.Instance<Table<Employee>>();
            // Isolate.WhenCalled(() => fakeDataContext.Employees).WillReturn(fakeEmployeeTable);
            // Isolate.WhenCalled(() => fakeEmployeeTable).WillReturnCollectionValuesOf(fakeEmployees);
            // or by transitivity
            Isolate.WhenCalled(() => fakeDataContext.Employees).WillReturnCollectionValuesOf(fakeEmployees);
        }

        [TestMethod]
        public void GetEmployeesByHireDate_should_return_hires_from_2008_until_present() {
            var employees = _repository.GetEmployeesByHireDate(new DateTime(2008, 1, 1), DateTime.Now);
            Assert.AreEqual(1, employees.Count());
            Assert.AreEqual(3, employees[0].EmployeeID);
        }
    }

The test method itself looks exactly as if we’d been testing against a real database. The difference lies in the Initialize method, where we setup the fake data context and database contents. We instruct TypeMock to return the fake context in place of the real one inside EmployeeRepository. And whenever someone calls the Employees property on the fake context, we have TypeMock intercept the call and return a fake collection of type IQueryable<Employee>. We could’ve returned an instance of Table<Employee>, which implements IQueryable<Employee>, but in this case returning the collection is simpler and sufficient. Had we had more methods on our repository, we likely would’ve added additional rows to the Employee table and populated more of its columns.

  • Share/Bookmark

Tags: , , ,
Posted in .Net | 3 Comments »

The given-expect testing pattern

Posted by Ronnie Holm on April 25th, 2010

I was watching Brett Schuchert’s TDD screencast on implementing the shunting yard algorithm in C#. In it Brett builds up his tests in a style I hadn’t come across before. Each test is expressed as a given-expect statement. A pattern that is particularly useful in situations in which a class has a main method that accepts an open-ended number of dissimilar inputs.

I found the given-expect pattern useful in testing a piece of code that I was working on this week. I was refactoring and adding tests around an ASP.NET control adapter that makes SharePoint 2007 pages more XHTML compliant. I wanted to reuse the transformations outside the control adapter and hence ended up moving the transformation logic to a new class. It accepts possibly malformed HTML and relies on heuristics of the HTML Agility Pack to build a DOM off of it. I can then query the DOM, looking for known violations, and patch them before returning XHTML to the caller.

    public class HtmlToXHtmlTransformer {
        private readonly HtmlDocument _document;

        public HtmlToXHtmlTransformer(string html) {
            _document = new HtmlDocument();
            _document.DetectEncoding(new StringReader(html));
            _document.LoadHtml(html);
        }

        private void Transform(string xpath, Action<HtmlNode> nodeMatch) {
            var nodes = _document.DocumentNode.SelectNodes(xpath);
            if (nodes != null)
                foreach (var node in nodes)
                    nodeMatch.Invoke(node);
        }

        private void FixDuplicateBorderAttributeOnSPGridViewControl() {
            Transform("//table[count(@border)=2]", node => node.Attributes.Remove("border"));
        }

        public string Transform() {
            FixDuplicateBorderAttributeOnSPGridViewControl();
            _document.OptionWriteEmptyNodes = true;
            return _document.DocumentNode.WriteTo();
        }
    }

The complete HtmlToXHtmlTransformer collects a dozen transformations. Its Transform method is what we want to call with various HTML fragments to verify that they come out as XHTML. For this purpose, we might do the tests as Visual Studio data-driven tests that read their input and output from a text file. But in most cases I prefer traditional tests, so I can describe the purpose of a test with a descriptive method name and possibly a comment.

    [TestClass]
    public class HtmlToXHtmlTransformerTest {
        private string _result;

        [TestMethod]
        public void Must_selfclose_nodes_when_allowed() {
            Given("<br>");
            Expect("<br />");
        }

        [TestMethod]
        public void Must_remove_duplicate_border_on_SPGridView_control {
            Given(@"<table border=""0"" border=""0""></table>");
            Expect(@"<table border=""0""></table>");
        }

        private void Expect(string xhtml) {
            Assert.AreEqual(xhtml, _result);
        }

        private void Given(string html) {
            var transformer = new HtmlToXHtmlTransformer(html);
            _result = transformer.Transform();
        }
    }

I particularly like the clarity of the given-expect pattern and find that for a reasonable number of tests it’s a viable alternative to data-driven test. I do, however, recognize the value of data-driven tests in situations where a non-developer wants to test a class. Though at the unit test level I’ve never experienced this. It’s more characteristic of FitNesse for acceptance testing. However you unit test, just make sure your tests run with a minimum of effort on your part and that they run fast.

  • Share/Bookmark

Tags: , , ,
Posted in .Net, SharePoint | No Comments »

Configuring Emacs through Emacs Lisp

Posted by Ronnie Holm on April 15th, 2010

I’ve been an Emacs fanboy for close to 15 years. For a long time I used Emacs solely on Linux because of it’s ubiquity. But written in C and Emacs Lisp, Emacs has great cross-platform support, and now I use it daily on Windows too. Installing Emacs on Windows is as straightforward as downloading and extracting the most recent Zip file.

Code equals data

Configuring the editor is done by placing Emacs Lisp code in the .emacs file. Whenever Emacs starts, it looks for this file in the directory specified by the HOME environment variable and executes its content. Unlike the XML configuration files of .NET and Java, with Emacs there’s no intermediate configuration format. There’s no extra language to learn and no limitation in the expressiveness of the configuration language. With this interchangeability of code and data, every behavior of Emacs can be hooked into and tailored and every global variable redefined.

Starting Emacs from the Windows taskbar

On my machine, I like everything Emacs-related to reside in the directory that I extracted Emacs to, yet I want to be able to start Emacs from the taskbar. I do this by pinning cmd.exe to the taskbar and modifying its destination so it defines HOME for this instance before spawning Emacs. This way the HOME of Emacs doesn’t conflict with the HOME of other applications.

    cmd.exe /C "set HOME=...\emacs-23.1&&...\emacs-23.1\bin\runemacs.exe"

My .emacs isn’t too esoteric. Nevertheless, here it is for posterity. Reading on, keep in mind that unless otherwise noted, all referenced packages come with Emacs 23.1.

General settings

I start off redefining a couple of global variables. Much functionality relies on the user name and mail address to be known in advance. I then remove the toolbar at the top of the Emacs window, because I use menus or keyboard shortcuts anyway. Next I disable the splash screen on startup, and redefine a few global variables governing Emacs’ scrolling behavior. By default scrolling isn’t line by line, but chuck by chuck of text. I find this behavior confusing.

    (setq user-full-name "Ronnie Holm")
    (setq user-mail-address "foo@bar.baz")

    (tool-bar-mode nil)                            ;; don't show the toolbar

    (setq inhibit-startup-message t                ;; don't show ...
          inhibit-startup-echo-area-message t)     ;; ... startup messages

    (setq scroll-margin 1                          ;; do smooth scrolling
          scroll-conservatively 100000
          scroll-up-aggressively 0.01
          scroll-down-aggressively 0.01)

Next I turn on automatic syntax highlighting and commands specific to known file types. Following that I turn the blinking square cursor into a solid and less distracting one. Also, I instruct Emacs not to retain backups of files that I edit or save. I don’t discount the value of backups, but I also don’t like having to remove backup and auto-save files when they clutter my folders. Instead  Emacs should move these files to the Windows Recycle Bin. Lastly, I enable iswitchb-mode, which makes switching buffers easier by providing on-the-fly suggestions.

    (global-font-lock-mode t)                      ;; always do syntax highlighting
    (blink-cursor-mode 0)                          ;; don't blink cursor
    (setq backup-inhibited t)                      ;; no backup files
    (setq delete-by-moving-to-trash t)             ;; delete moves to recycle bin
    (iswitchb-mode t)                              ;; easy buffer switching

The last of the general settings involve modifications to the modeline at the bottom of the Emacs window. By default it displays the buffer name, the line number, and the modes Emacs is in. I extend the modeline with the column cursor position and the size of the current buffer.

    (column-number-mode t)                         ;; show column numbers
    (size-indication-mode t)                       ;; show file size

Package settings

Oftentimes I find myself editing the same set of files every day. So having the cursor move to where I left it editing the file the last time is handy. This is done by save-place mode. Behind the scenes it stores a file name/offset mapping in a file below HOME.

    (setq save-place-file "~/.emacs.d/saveplace")  ;; location of saveplace file
    (setq-default save-place t)                    ;; activate for all buffer
    (require 'saveplace)

As hinted by Getting organized with Emacs Org-mode, I very much enjoy using Org-mode for keeping notes, maintaining lists, and much more. The next section of my .emacs is therefore dedicated to customizing org-mode. Firstly, to make documents easier to read, instead of displaying all the asterisks that designate an indentation level, only display the last one. Secondly, align each indentation level by always adding two asterisks on indentation. Thirdly, when clocking time, have Emacs remember what I was doing and for how long across restarts. But remove clocked time less than one minute.

    (setq org-hide-leading-stars t)                ;; hide but one star in outline
    (setq org-add-levels-only t)                   ;; align items nicely
    (setq org-clock-persist t)                     ;; keep track of time ...
    (org-clock-persistence-insinuate)              ;; ... across sessions
    (setq org-clock-out-remove-zero-time-clocks t) ;; remove 0-duration clocked

The default Emacs color theme looks kind of dull. So I downloaded the color-theme package and selected a more aesthetically pleasing theme. After downloading color-theme, place its Lisp files in ~/site-lisp. That’s one of the places where Emacs will automatically look for packages. The 300 or so packages that come with Emacs are in the ~/lisp folder.

    (require 'color-theme)                         ;; use a color theme
    (color-theme-initialize)
    (color-theme-arjen)

My last additions to .emacs involve Haskell. Emacs doesn’t support Haskell out-of-the-box. But a haskell-mode is available for download. It turns Emacs into a decent Haskell development environment. Besides syntax highlighting and code formatting capabilities, it adds to Emacs commands for interacting with the Haskell compiler and Haskell interactive.

    (load "~/site-lisp/haskell-mode-2.6.4/haskell-site-file")
    (add-hook 'haskell-mode-hook 'turn-on-haskell-doc-mode)
    (add-hook 'haskell-mode-hook 'turn-on-haskell-indentation)

This concludes my .emacs. Quite a few of these settings I picked up reading the emacs-fu blog.

  • Share/Bookmark

Tags:
Posted in Linux, Windows | No Comments »

SharePoint Saturday EMEA virtual conference

Posted by Ronnie Holm on April 4th, 2010

Back in January, I attended the one-day virtual SharePoint Saturday EMEA conference. It was my first virtual conference so I was excited to see how it would work out. Presenting through Office Live Meeting and interacting with the audience through text-only is definitely a challenge compared to live presentations. But I’d say it went well with 50-60 attendees at each of the three parallel tracks.

Here’re the talks that I attended, all recorded and available with slides.

SharePoint 2010 Planning and Best Practice Approaches to Upgrade

Upgrading to SharePoint 2010, you should first establish a copy of your existing environment on the latest patch level. Then run the stsadm command with the new PreUpgradeChecker option. Make sure your environment has no unused features, site templates, and so on, and identify everything that has changed from out-of-the-box by running a tool like WinMerge on the 12 hive. Also, assert that no pages has been ghosted, and don’t attempt to upgrade your SharePoint 2007 master page. Start with the 2010 ones and add in your 2007 modifications. SharePoint 2010 ships with both 2007 and 2010 master pages, but SharePoint 2007 and 2010 isn’t binary compatible.

Make sure all hardware requirements are satisfied: 8 GB RAM at the minimum on the Windows 2008 servers running SharePoint and MS SQL Server. On the client you need Internet Explorer 7 or 8 or Firefox 3.x to author content. Internet Explorer 6 isn’t supported. Not even with a degraded reader experience. The SharePoint 2010 development environment should be setup with Visual Studio 2010 on Windows Vista or Windows 7 in order to compile, debug, build, and deploy right out of Visual Studio 2010.

Understanding, using, and customizing PowerShell for a SharePoint 2010 Environment

This talk started with some PowerShell history and basics. PowerShell is made up of a shell that executes commands and an integrated scripting environment for development. .NET compiled code, called cmdlets, are the executable units combined using the PowerShell pipeline. The PowerShell language itself is dynamic and loosely typed, so being able to express yourself tops performance. Scripts may be compiled and deployed as a SnapIn, consisting of compiled DLLs and registry updates, or as a module using xcopy deployment.

SharePoint 2010 ships with 650 cmdlets, and its own base class for writing additional SharePoint cmdlets.

Design and Manage Site Collections in SharePoint 2010

By default every single site collection within a web application goes into one rapidly growing database (think about users migrating from file shares to site collections). Such a large database takes time to backup and restore. Hence, with SharePoint 2010, consider partitioning site collections into their own databases from the beginning. After a database is created, map it to one and only one site collection. Then, instead of putting a size limit on the web application, put it on the site collection itself.

In SharePoint 2007 you had to create multiple Shared Service Providers (SSP) if site collections had different needs or you didn’t want a site collection to access parts of an existing SSP. With SharePoint 2010, application services can now be shared between site collections.

With sandbox solutions, the solution is deployed to the database hosting the site, rather than to front-end servers. This makes it easier to deploy code, but the code is limited in what it can do, and you may have to set resource quotas across the site collection.

SharePoint 2010, Getting Ready

This talk provided an overview of SharePoint 2010. WSS 3.0 becomes SharePoint Foundation 2010 and MOSS 2007 becomes SharePoint Server 2010. Business Connectivity Services (BCS) are no longer part of the server edition, but has been moved to Foundation. A lot more services have been added, like state service, usage and health service, and Visio graphics service. Generally, with all the improvements to deployment and upgrade with PowerShell and the addition of multi-tenancy for the SSP, SharePoint 2010 is better in a hosting scenario.

The web user interface has been made more Office-like with the addition of the ribbon and the use of AJAX. In document libraries you can create document sets as a way to relate documents to each other and have versioning and workflow follow every document in the set. Through the BCS, you can expose external data as native SharePoint lists with full CRUD capabilities.

SharePoint 2010 Development Tips and Tricks

The focus of the first part this talk is on the SharePoint 2010 Foundation features. Instead of developing against the web services or the object model, you can use the new managed client object model. This way, you can work against SharePoint from .NET code, from a Silverlight application, or from JavaScript. Behind the scenes, the client object model works against a WCF service running on the SharePoint server, which talks to the server object model on the server, and returns JSON to the client.

The second part of this talk is about sandbox solutions. This feature provides site collection users with the ability to upload and deploy WSPs. Finally, the third part of the talk is about the fluid integration model, which solves the problem of accessing cross-domain resources, e.g., having a Silverlight application access information on a SharePoint server on a different domain.

Installing and Configuring SharePoint Server 2010 in a Virtual Environment

This talk recommends that everyone read the MS whitepaper on Virtualization of Microsoft SharePoint Products and Technologies. Configuring a development environment, the dilemma is weather to create one virtual machine hosting everything or one virtual machine for the MS SQL Server, the Active Directory, and the SharePoint server each. The presenter suggests a middle ground. Still, it’s important to create a number of service accounts and use them in your development environment rather than running everything as administrator.

The SharePoint 2010 installer comes with a prerequisite installer that goes onto the web and downloads required software. After that, you can run the SharePoint server installer. Here you can choose between Standalone and Server farm, but always pick server farm. Standalone should only be used for demo purposes.

  • Share/Bookmark

Tags: ,
Posted in SharePoint | No Comments »

Getting started with SharePoint presentation

Posted by Ronnie Holm on March 31st, 2010

Download slides from the presentation.

Last week at work I did a 45 minutes presentation on how to get started with SharePoint development. Instead of the usual presentation on the technical merits of SharePoint, my focus was more on the change in mindset required coming from ASP.NET. For even though ASP.NET is a cornerstone of SharePoint, SharePoint is so much more. Not to mention different.

History makes a difference

SharePoint is a long-evolving product, dating back to the late nineties. From its inception and up till now new technologies have replaced old ones, APIs have emerged and died, product teams have merged, and Microsoft have bought and integrated other companies’ products into SharePoint. At the same time SharePoint has become the fastest growing server product in Microsoft history. All of this inevitably leaves its marks on the APIs, which aren’t as consistent and defect free as we’re used to with the .NET framework.

Provisioning is the magic sauce

What truly makes SharePoint development different from ASP.NET is the notion of provisioning. With ASP.NET you create a bunch of ASPX files, organize them in a static file structure, and deploy them to a server. With SharePoint, the structure emerges over time as SharePoint or the user creates instances of templates: sites from site templates, lists from list templates, pages from page templates, and so forth. From a developer’s perspective the challenge isn’t the instance creation in itself. It’s that SharePoint encourages users to not only dynamically evolve the structure, but also to modify the instances, severing their definition from the template. While it empowers users, it also makes it challenging to programmatically evolve the structure.

Developing with SharePoint is about creating templates and components for SharePoint or the user to compose a site of. To make this composition work, SharePoint imposes constraints on what can be done and how. While any constraint may at times be perceived as a hindrance, accepting it is what guarantees that a components will play nicely with others. These pieces of functionality are then packaged as features and added to a WSP installation file for deployment to SharePoint. Features may then be activated, making their functionality available to a site. Or deactivated and the WSP uninstalled.

Why learn SharePoint

By the end of the day, no doubt SharePoint is more challenging to work with than ASP.NET. Not acknowledging its history makes many ASP.NET developers so frustrated that they’ll never again want to work with SharePoint. Coming from ASP.NET I can understand why. At times SharePoint isn’t as smooth and evolved as ASP.NET. But knowing what to expect takes the worst of the frustration. And once you learn to leverage the power of SharePoint, you can build applications without writing a lot of plumping code. To a large extend the architecture is given, leaving you with the opportunity to fill in the blanks.

  • Share/Bookmark

Tags: , ,
Posted in .Net, SharePoint | No Comments »

SharePoint list access using the Repository pattern

Posted by Ronnie Holm on January 18th, 2010

(Download code here. See related post on SharePoint list definition using the Template pattern)

Maybe it’s that the SharePoint API is hard to use. Maybe it’s that coding against SharePoint is about making smaller additions here and there. Maybe it’s that the Patterns & Practices SharePoint Guidance isn’t widely known. Whatever the reason, developing for SharePoint requires equal attention to the separation of presentation, business, and data access code. Hence, starting with data access, we may want to create a repository and route queries through it (the SharePoint Guidance outlines a more sophisticated implementation than the one below):

    [TestClass]
    public class EmployeesRepositoryTest {
        private SPSite _siteCollection;
        private SPWeb _site;
        private EmployeesRepository _repository;

        private readonly Employee _duffyDuck = new Employee {
            Id = 1000, Name = "Duffy Duck", HireDate = new DateTime(2009, 12, 1),
            Remarks = "Looks like a duck, quacks like a duck, probably is a duck"
        };
        private readonly Employee _porkyPig = new Employee {
            Id = 1001, Name = "Porky Pig", HireDate = new DateTime(2010, 2, 1)
        };
        private readonly Employee _sylvesterTheCat = new Employee {
            Id = 1002, Name = "Sylvester the Cat", HireDate = new DateTime(2010, 3, 1)
        };
        private readonly Employee _bugsBunny = new Employee {
            Id = 1100, Name = "Bugs Bunny", HireDate = new DateTime(2010, 1, 1)
        };

        public void AddEmployees() {
            _repository.AddEmployee(_site, _duffyDuck);
            _repository.AddEmployee(_site, _porkyPig);
            _repository.AddEmployee(_site, _sylvesterTheCat);
        }

        public void ClearEmployees() {
            var definition = new EmployeesDefinition();
            var employees = _site.Lists[definition.ListName];
            while (employees.Items.Count > 0)
                employees.Items.Delete(0);
        }

        [TestInitialize]
        public void Initialize() {
            _siteCollection = new SPSite("http://localhost");
            _site = _siteCollection.OpenWeb("/");
            _repository = new EmployeesRepository();
            ClearEmployees();
            AddEmployees();
        }

        [TestCleanup]
        public void Cleanup() {
            _site.Dispose();
            _siteCollection.Dispose();
        }

        [TestMethod]
        public void AddEmployee_should_add_valid_employee() {
            _repository.AddEmployee(_site, _bugsBunny);
            var e = _repository.GetEmployeeById(_site, _bugsBunny.Id);
            Assert.AreEqual(_bugsBunny.Id, e.Id);
            Assert.AreEqual(_bugsBunny.Name, e.Name);
            Assert.AreEqual(_bugsBunny.HireDate, e.HireDate);
            Assert.AreEqual(_bugsBunny.Remarks, e.Remarks);
        }

        [TestMethod]
        public void GetEmployeesHiredBetween_should_return_2010_hires() {
            var from = new DateTime(2010, 1, 1);
            var to = new DateTime(2010, 12, 31);
            var employees = _repository.GetEmployeesHiredBetween(_site, from, to);
            Assert.AreEqual(2, employees.Count);
            Assert.AreEqual(_porkyPig.Id, employees[0].Id);
            Assert.AreEqual(_sylvesterTheCat.Id, employees[1].Id);
        }
    }

In the words of Martin Fowler, here’s the essence of the Repository pattern:

A Repository mediates between the domain and data mapping layers, acting like an in-memory domain object collection. Client objects construct query specifications declaratively and submit them to Repository for satisfaction. Objects can be added to and removed from the Repository, as they can from a simple collection of objects, and the mapping code encapsulated by the Repository will carry out the appropriate operations behind the scenes. Conceptually, a Repository encapsulates the set of objects persisted in a data store and the operations performed over them, providing a more object-oriented view of the persistence layer.

In SharePoint terms, business logic should query a repository which in turn queries a SharePoint list. Within the repository, the weakly typed items returned are then mapped to strongly typed data transfer objects, which are returned to the business layer.

With this approach to data access comes a number of advantages: (1) duplicate data access code is eliminated. Only within the repository do we setup the query and transform the weakly typed SPListItemCollection into strongly typed data transfer objects. (2) The list definition classes introduced in SharePoint list definition using the Template pattern may be used to construct CAML queries from strongly typed field names. Lastly, (3) accessing data through a repository makes it easier to mock the data access part of the application and to integration test that part.

The code below is a simple, yet usable, implementation of the Repository pattern. The idea is to have all repositories inherit from a common base class. Its purpose is to wrap the querying of a list and to log what’s going on. Because it’s a base class, it shouldn’t know how to transform the weakly typed result into strongly data transfer objects or which CRUD operations a particular repository supports:

    public abstract class ListRepository {
        protected ListDefinition Definition { get; set; }
        protected SPListItemCollection Result { get; set; }

        protected void Query(SPWeb site, string caml) {
            AssertValidSite(site);
            AssertValidCaml(caml);
            AssertListExistence(site);
            AssertListDefinitionSetBySubclass();

            var watch = new Stopwatch();
            var list = site.Lists[Definition.ListName];
            var query = new SPQuery {Query = caml};
            Debug.WriteLine(
                string.Format("About to run query against list '{0}': {1}", list, caml));
            watch.Start();
            Result = list.GetItems(query);
            watch.Stop();
            Debug.WriteLine(
                string.Format("Query against '{0}' returned {1} rows in {2} ms",
                              list, Result.Count, watch.ElapsedMilliseconds));
        }

        protected void AssertListExistence(SPWeb site) {
            if (!ListDefinition.ListExists(site, Definition.ListName))
                throw new ArgumentException(
                    string.Format("No '{0}' list on site '{1}'", Definition.ListName, site.Url));
        }

        protected void AssertListDefinitionSetBySubclass() {
            if (Definition == null)
                throw new NullReferenceException(
                    string.Format(
                        "Sublcass must set Definition property prior querying '{0}' list",
                        Definition.ListName));
        }

        protected void AssertValidCaml(string query) {
            if (string.IsNullOrEmpty(query))
                throw new NullReferenceException("Query must not be null or empty");
        }

        protected void AssertValidSite(SPWeb site) {
            if (site == null)
                throw new NullReferenceException("Site must not be null");
        }
    }

Each ListRepository connects to a corresponding ListDefinition, holding the name of the list to query and its strongly typed field names. It’s the responsibility of a concrete repository to set the Definition property prior to doing any querying. After running a query, the Result property holds the weakly typed result, which a concrete repository can then transform into data transfer objects to be passed to the business layer.

As an example, add to the concrete EmployeeRepository any CRUD method you see necessary to fulfill the business requirements:

    public class EmployeesRepository : ListRepository {
        public EmployeesRepository() {
            Definition = new EmployeesDefinition();
        }

        public void AddEmployee(SPWeb site, Employee e) {
            var list = site.Lists[Definition.ListName];
            var item = list.Items.Add();
            item[EmployeesDefinition.EmployeeId] = e.Id;
            item[EmployeesDefinition.Name] = e.Name;
            item[EmployeesDefinition.HireDate] = e.HireDate;
            item[EmployeesDefinition.Remarks] = e.Remarks;
            item.Update();
        }

        public Employee GetEmployeeById(SPWeb site, int id) {
            var caml =
                string.Format(@"
                      <Where>
                        <Eq>
                          <FieldRef Name=""{0}"" />
                          <Value Type=""Integer"">{1}</Value>
                        </Eq>
                      </Where>",
                    EmployeesDefinition.EmployeeId, id);
            Query(site, caml);

            IList<Employee> employees = Map(Result);
            if (employees.Count == 0)
                throw new ArgumentException(string.Format("No employee with id = {0} exists", id));
            return employees[0];
        }

        public ReadOnlyCollection<Employee> GetEmployeesHiredBetween(SPWeb site, DateTime from, DateTime to) {
            var caml =
                string.Format(@"
                      <Where>
                        <And>
                            <Geq>
                              <FieldRef Name=""{0}"" />
                              <Value IncludeTimeValue=""TRUE"" Type=""DateTime"">{1}</Value>
                            </Geq>
                            <Leq>
                              <FieldRef Name=""{0}"" />
                              <Value IncludeTimeValue=""TRUE"" Type=""DateTime"">{2}</Value>
                            </Leq>
                        </And>
                      </Where>",
                    EmployeesDefinition.HireDate,
                    SPUtility.CreateISO8601DateTimeFromSystemDateTime(from),
                    SPUtility.CreateISO8601DateTimeFromSystemDateTime(to));
            Query(site, caml);
            return new ReadOnlyCollection<Employee>(Map(Result));
        }

        protected IList<Employee> Map(SPListItemCollection items) {
            var employees = new List<Employee>();
            foreach (SPItem item in items) {
                var e = new Employee {
                                Id = (int)item[EmployeesDefinition.EmployeeId],
                                Name = (string)item[EmployeesDefinition.Name],
                                HireDate = (DateTime)item[EmployeesDefinition.HireDate],
                                Remarks = (string)item[EmployeesDefinition.Remarks]
                            };
                employees.Add(e);
            }
            return employees;
        }
    }

Calling the GetEmployeeById or GetEmployeesHiredBetween methods, the caller is required to pass in an SPWeb instance pointing to the the site holding the list to query. Outside the SharePoint context, you have to manually create this instance, like with the integration tests above. But within the SharePoint context, callers are likely to just pass in SPContext.Current.Web.

The above repository implementation deliberately ignores any issue of caching. If you find the need for it, however, you can replace SPList.GetItem with PortalSiteMapProvider.GetCachedListItemsByQuery. The advantage of using the PortalSiteMapProvider over Asp.Net caching of the result is that the provider takes care of invalidating cache entries when items are modified. The disadvantage is that the provider is part of the SharePoint publishing API, which isn’t part of WSS 3.0. In addition, it’s only available from code running within SharePoint, and likely requires cache settings to be tweaked.

      Another, non-trivial, improvement would include the use of the Unit of Work pattern. A commonly used pattern in ORMs because it offers a way to “keep track of everything you do during a business transaction that can affect the database. When you’re done, it figures out everything that needs to be done to alter the database as a result of your work". Like with the DataContext class in LINQ to SQL or the DataSet class in ADO.NET, it could add transaction support to SharePoint lists.

      • Share/Bookmark

      Tags: , ,
      Posted in .Net, SharePoint | 1 Comment »

      SharePoint list definition using the Template pattern

      Posted by Ronnie Holm on January 11th, 2010

      (Download code here. See related post on SharePoint list access using the Repository pattern)

      Books on SharePoint often show how to create lists from code by calling the SharePoint API from directly within a feature receiver. This receiver would then contain in-place string literals for column names, create the columns, update the default view, and so on. While such an approach provides for an nice demonstration of the SharePoint API, it tends to carry over into production code.

      My take on feature receivers, however, is that they should contain the least possible amount of code. Staying true to object-orientation and separation of concerns, list definition and creation should instead consist of a common set of classes and methods to be called from the receiver:

          public override void FeatureActivated(SPFeatureReceiverProperties p) {
              using (var site = p.Feature.Parent as SPWeb) {
                  var employees = new EmployeesDefinition();
                  if (!ListDefinition.ListExists(site, employees.ListName))
                      employees.CreateOnSite(site);
              }
          }

      The first area to improve on is that of string literal field names getting duplicated across the code base. String literals make it impossible for the compiler to enforce a consistent naming of columns. As column names are used in defining the list, in forming CAML queries against it, and in accessing the result, misspelled column names is a common source of runtime errors. The second area to improve on is that of duplication of code for doing common list operations, like checking for the existence of the list or removing its title column. Lastly, we want to get rid of duplicate control logic, i.e., verifying preconditions and calling the same series of methods with every list definition.

      One approach to improving on these areas is to start by defining a base class for list definitions. The base class combines helper methods, working on lists, with the Template pattern for defining the common steps of list creation:

          public abstract class ListDefinition {
              public string ListName;
              public string ListDescription;
              protected SPList List;
      
              public void CreateOnSite(SPWeb site) {
                  if (string.IsNullOrEmpty(ListName))
                      throw new ArgumentException("Expected not null or not empty list name member");
                  if (site == null) throw new NullReferenceException("Expected valid site");
                  CreateList(site);
                  if (List == null) throw new NullReferenceException("Expected list member not null");
                  CreateFields(List);
                  UpdateDefaultView(List);
                  SetAdditionalProperties(List);
              }
      
              protected abstract void CreateList(SPWeb site);
              protected virtual void CreateFields(SPList l) {}
              protected virtual void UpdateDefaultView(SPList l) {}
              protected virtual void SetAdditionalProperties(SPList l) {}
      
              public static void HideAndMakeTitleFieldNotRequiredOnItemNewAndEditPage(SPList l) {
                  var title = l.Fields.GetField("Title");
                  title.Required = false;
                  title.Hidden = true;
                  title.Update();
              }
      
              public static bool ListExists(SPWeb site, string listName) {
                  if (string.IsNullOrEmpty(listName))
                      throw new ArgumentException("ListNameMustNotBeNullOrEmpty", listName);
                  SPList list = null;
                  try {
                      list = site.Lists[listName];
                  }
                  catch (ArgumentException) {
                      // list not found
                  }
                  return list != null ? true : false;
              }
          }

      At the core of the Template pattern is the template method. It defines the steps of an algorithm through a series of method calls. Each either abstract or virtual depending on if the step is mandatory or voluntary in the algorithm. Subclasses then specify the behavior of individual steps by implementing or overriding methods. In case of the ListDefinition class, CreateOnSite is our template method. It ensures that context, in the form of an SPList instance, is passed along to each step in the algorithm.

      Each subclass defines the specific characteristics of a list. It defines constants for column names and their data types, the views and which column to index, and so on. This makes for a concise, easy to read, and consistent list definition:

          public class EmployeesDefinition : ListDefinition {
              public const string EmployeeId = "EmployeeId";
              public const string Name = "Name";
              public const string HireDate = "HireDate";
              public const string Remarks = "Remarks";
      
              public EmployeesDefinition() {
                  ListName = "AcmeEmployees";
                  ListDescription = "Employees at Acme Corp.";
              }
      
              protected override void CreateList(SPWeb site) {
                  var guid = site.Lists.Add(ListName, ListDescription, SPListTemplateType.GenericList);
                  List = site.Lists[guid];
              }
      
              protected override void CreateFields(SPList l) {
                  l.Fields.Add(EmployeeId, SPFieldType.Integer, true);
                  l.Fields.Add(Name, SPFieldType.Text, true);
                  l.Fields.Add(HireDate, SPFieldType.DateTime, true);
                  var remarks = (SPFieldMultiLineText) l.Fields[l.Fields.Add(Remarks, SPFieldType.Note, false)];
                  remarks.RichText = true;
                  remarks.RichTextMode = SPRichTextMode.FullHtml;
                  remarks.Update();
                  l.Update();
              }
      
              protected override void UpdateDefaultView(SPList l) {
                  var v = l.DefaultView;
                  v.ViewFields.Delete("LinkTitle");
                  v.ViewFields.Add(EmployeeId);
                  v.ViewFields.Add(Name);
                  v.ViewFields.Add(HireDate);
                  v.ViewFields.Add(Remarks);
                  v.Update();
              }
      
              protected override void SetAdditionalProperties(SPList l) {
                  HideAndMakeTitleFieldNotRequiredOnItemNewAndEditPage(l);
                  l.Fields[HireDate].Indexed = true;
                  l.Update();
              }
          }

      Since the string literals have now become public constants, we get IntelliSense and compile-time checking referencing them. In addition, by defining common operations on the base class and using the Template pattern, we reduce the amount of code that would otherwise have to go into each definition. Finally, the base class asserts, on behalf of all subclasses, that the list name is set before attempting to create the list and that the SPList field is set after calling the CreateList method.

      • Share/Bookmark

      Tags: , ,
      Posted in .Net, SharePoint | 1 Comment »

      Planning for 2010

      Posted by Ronnie Holm on January 4th, 2010

      In my previous post I looked at 2009 in hindsight. Consequently, in this one I look ahead at 2010 and what I want to accomplish professionally this coming year. I don’t plan on anything too esoteric. Instead, I want to consolidate my skills around building web applications with C#.

      My goals for the coming year are:

      • Focus more on architecture and design. Not in the architecture astronaut connotation. But as in becoming more aware of how to build better software. I want to apply the SOLID principles more consciously and re-read classics such as Design Patterns: Elements of Reusable Object-Oriented Software and Patterns of Enterprise Application Architecture.
      • Continue exploring LINQ. It’s a fascinating technology that’s going to get only more pervasive in years to come. Truly understanding LINQ is key to getting into the habit of applying a more functional and succinct style to my own code. To get started on this endeavor I’m going to read and apply LINQ in Action.
      • Learn Entity Framework. Using an object-relational mapper should be second-nature to any developer. In the past the light-weight LINQ to SQL has served me well. Still, I want to step up and learn how Entity Framework deals with the impedance mismatch. I want to write an application that uses Entity Framework.
      • Become better at browser technologies. JavaScript and jQuery are high on the list, but I want to improve on HTML and CSS as well. My goal isn’t to become an HTML or CSS Jedi. I simply want to have enough knowledge to avoid making rookie mistakes. The technologies all come together in jQuery, making Learning jQuery a good starting point. Besides, I want to use a tool like Firebug to learn from others.
      • Be on top of SharePoint 2010. SharePoint 2007 and 2010 is what I want to work with daily. That doesn’t imply me not keeping up to speed with the rest of .NET. Just that SharePoint will act as my gateway to other technologies. The great thing about SharePoint is that development is often split between working inside and outside SharePoint.
      • Become more involved in higher-level development decisions. By the end of the day, developers don’t deliver software, they deliver value to stakeholders. Writing code is but a means to that end. I want to be involved in all steps from conception to completion.

      To me these points strike a good balance between technical and non-technical goals and between short and long term goals. However, by the end of the day, building great software is about being attentive to the entire stack and its surroundings.

      • Share/Bookmark

      Tags:
      Posted in Uncategorized | No Comments »

      2009 in retrospect

      Posted by Ronnie Holm on December 28th, 2009

      As 2009 is drawing to a close, it’s time to look back and see what I’ve accomplished this past year. My professional goals for 2009 were to work on challenging software development tasks, preferably on larger projects. I wanted to continue to grow my skills working with .Net in general and SharePoint in particular. In addition, I wanted to be more involved with higher-level development decisions, such as requirements gathering and solution design.

      So how did the year go?

      • Changed jobs to one that gravitates more around larger projects. The rationale being that larger projects come with larger engineering challenges. I spend six months on an Asp.Net project followed by three on a SharePoint project. For various reasons, I wasn’t as involved in higher-level development decisions as I would’ve liked to.
      • Did two presentations. One on Unit testing and mocking for the Asp.Net project that I was working on at the time. The other presentation was on Parallel page rendering with Asp.Net and SharePoint for my current project. None involving rocket science, but I find so few are familiar with the techniques.
      • Made my way through three certifications. The 70-536: MS .NET Framework, Application Development Foundation, 70-562: MS .NET Framework 3.5, ASP.NET Application Development, and Prince2 Foundation. I’ve mixed feelings with regard to certifications, though. Certainly, I learned valuable lessons studying for each one. Yet, given the same amount of time, I’m inclined to think I would’ve learned more studying books, blogs, listening to various podcasts, and writing.
      • Attended the Jaoo conference on software engineering. It was my first time ever attending a conference and it sure was enlightening. I intentionally went for a conference not tied to a specific vendor because I felt I’d learn more that way. My issue with Microsoft conferences like Tech-Ed or PDC is their focus on the latest technology buzz. Buzz that quickly becomes obsolete or is already heavily exposed on the web. Not to mention that most sessions are available online afterward.
      • Learned functional programming. My focus on new technology has mostly been on various aspects of functional programming. A subject that’s interested me for years, but one that’s only recently started to permeate C#, my language of choice. I learned a great deal about F# when I generated fractal terrains and about XSL when I had to jump through functional loops and about functional programming in general.
      • Wrote 16 blog posts (25 pages, 10,000 words). Compared to previous years it’s a record. Naturally, not all posts were equally good. Nevertheless I enjoyed learning about the subjects and feel they helped advance my writing skills. The posts on Basic unit testing guidelines and Why not to comment code did manage to gain traction on Reddit, though.

      All things considered, I’m pleased with 2009. The only thing I regret is not being more involved in higher-level development decisions. I like coding, but it’s a means to an end. Being involved with a task from start to finish is what ignites my fire. I must push harder on that in 2010.

      • Share/Bookmark

      Tags:
      Posted in Uncategorized | 1 Comment »

      Printing iframe content using JavaScript

      Posted by Ronnie Holm on December 17th, 2009

      JavaScript is on top of the list of things I’d like to become better at. So I was quite happy when assigned a JavaScript-related defect in an application at work. Apparently, there was a bug in the JavaScript routine used for printing only the content of an iframe on a page. Rather than printing only the iframe’s content, it printed the page hosting the iframe, cropping parts of the iframe’s content.

      I started out confident that printing would be easy to fix. But after Googling and playing around with JavaScript for a while, frustration, fueled by the number of non-working hits I’d stumbled on, started to grow on me. Suppose you start out with an HTML document hosting an iframe and a few lines of JavaScript.

        <html>
          <head>
            <title>IFrame printing example</title>
            <script type="text/javascript">
              function myPrint() {
                var browser = navigator.appName;
                if (browser == "Microsoft Internet Explorer") {
                  window.frames["frame"].focus();
                  window.frames.print();
                }
                else if (browser == "Netscape")
                  alert("Printing not supported in Firefox");
              }
            </script>
          </head>
          <body>
            <iframe id="frame" name="frame" width="100"
                    height="100" src="http://google.com">
            </iframe>
            <a href="#" onclick="javascript:myPrint();">Print</a>
          </body>
        </html>

      A number of issues arise when printing the iframe. First you need to consider if you’re always hosting the main document on the same domain as the iframe’s source. If so, printing only the iframe with Internet Explorer works like a charm. If, on the other hand, the main document and the iframe’s source reside on different domains, it triggers Internet Explorer to displays a bar across the top of the window.

      Now, to print the iframe’s content, you must allow blocked content. Only then can JavaScript access the iframe’s object model. But at the same time, you make yourself vulnerable to cross-site scripting attacks.

      As far as Firefox support goes, you can issue the same API calls as for Internet Explorer. But Firefox will always print the main page, including only the visible parts of the iframe. To my knowledge there’s no way to make Firefox print the iframe’s content as seamlessly as Internet Explorer. One workaround, though, would be to open a new window, grab a reference to the iframe element, and move its contents to the new window before printing it. For cross-domain content, however, Firefox responds with a “permission denied” error when accessing the iframe element. And there’s no option to allow blocked content. Another workaround may therefore be to use Ajax to retrieve the source of the iframe for any domain and insert it into the new window. That, however, wouldn’t work in my case since the iframe may contain a form that the user may have started filling out before hitting print.

      As a last resort, I considered writing a proxy to retrieve cross-domain hosted content. This would make Internet Explorer never display the bar and allow Firefox to always open a new window with the iframe’s content loaded, even if the user started filling out a form first. But this approach sort of defies the purpose of the browser bar and the permission denied error. Unless you absolutely trust your iframe’s source, you’re exposing your users without their consent.

      In the end I went with the simplest and most secure solution of not supporting printing at all.

      • Share/Bookmark

      Tags: , ,
      Posted in Uncategorized | 2 Comments »