Building a Samson MVC site

Ever since I started using uSiteBuilder on my Umbraco projects I became attached to the strongly typed method of getting document type data from a node. I found the mix of getting intellisense and being able to use proper OO principles both liberating and powerful. After a while however I found that relying solely on one data provider (e.g. uSiteBuilder) was a huge risk; if it turned out to be faulty, inactive or incompatible with a later version of Umbraco I was stuck with a project that couldn't be updated without changing huge amounts of code. I decided to start thinking of a way to structure my Umbraco applications in a way that retained the benefits but lessened the risks.

Samson

The core of Samson is nothing more than a selection of interfaces concerned with the content and media sections of Umbraco. The implementations of these interfaces are intentionally in a separate project to enable them to be switched out completely with ease. The standard implementation of these interfaces are in an assembly called Samson.Standard. Whilst not basic, this implementation is not nearly as advanced as a mapper like Glass (yet) as there is still some manual coding to map the Umbraco properties to those on the models. There are however some features that make it nice to use. An example of this is the fact that it always instantiates the most specific type possible; this is slightly different than straight forward mappers. For example:

// The class representation of current page is of the type Article which inherits from Page
// --------- // Samson // --------- var page = _strongContentService.GetCurrentNode<Page>(); var samsonType = typeof(page); // Article
// --------------------- // Glass / Other Mappers // --------------------- var page2 = _context.GetCurrentItem<Page>(); var glassType = typeof(page2); // Page

This allows you to use the returned objects as you would in a normal OO situation, with all their polymorphic goodness intact.

Samson.Standard.Mvc & Samson.Mvc.{IocContainer}

The is also support for adding Samson into an MVC project, currently in 2 configurations. For those that haven't got into the IOC container hype there is a standard configuration that overrides the default controller factory with one that populates the StrongContentService and StrongMediaService on a SamsonSurfaceController. This is simple and works well, but isn't exactly extensible; the recommended approach is to use a dependency injector in the controller factories, and in the source I have included a Ninject example. I get lots of stick at work for using Ninject, they think that it is the worst thing to hit the .Net world since DNN, but come on, Ninjas, who cares about performance. All you have to do is pass your Ninject kernel into the NinjectControllerFactory at startup and as if by magic you can use constructor injection in your controllers, lovely.

var kernel = new StandardKernel(new NinjectModule());

ControllerBuilder.Current.SetControllerFactory(
 new Samson.Mvc.Ninject.NinjectControllerFactory(kernel)
);

GlobalConfiguration.Configuration.Services.Replace(
 typeof(IHttpControllerActivator),
 new NinjectWebApiControllerFactory(kernel));

Samson Mvc Site

Finally there's the starter site, an easy way to get started; this can be downloaded from GitHub. This is a simple solution including all the basic code for hooking up the Samson components with an Umbraco installation. This implementation follows the architecture shown below, though slightly more simplistic.

Some description

Domain Model Project (Samson.Model)

In this solution the domain model project actually contains the concrete model layer, the abstract model layer and the domain model layer. As this is just a demo / starter project I didn't want to go too crazy with solution size at the start.

Concrete Model => Samson.Model.DocumentTypes & Samson.Model.MediaTypes

Abstract Model => Samson.Model.DocumentTypes.Interfaces

Domain Model => Samson.Model.Repositories & Samson.Model.Services

Website Project (Samson.Website)

In the website project it is possible to see how we use MVC in this architecture. Some choose to use route hijacking to use MVC in a more pure state, however I like to keep the component nature of Umbraco intact; in this architecture a macro partial is used only to call an action on a controller. The benefits of this include using Umbraco caching on macros and being able to use the Macro Container data type to create configurable pages.

Comments

comments powered by Disqus