Session and Unit Of Work for Dynamic Data Store
I’ve created a couple of classes that make it even easier to work with the Dynamic Data Store:
DynamicDataStoreSession
This wraps the main functionality of a DynamicDataStore instance with the following additional benefits:
- Thread Safe – Ensures all calls to a session instance are done from the same thread that created it and throws an exception if not. This is done because a DynamicDataStore instance is not thread safe but has no enforcement thus resulting in weird errors when used from multiple threads
- Specify Type Only Once - When working with the DDS you need to specify the Type in the call to DynamicDataStoreFactory.CreateStore/GetStore and then again when calling Load / Find / Items etc. on a DynamicDataStore instance. This is because the Type passed to CreateStore/GetStore is used to derive the store's name and the Type passed to Load / Find / Items defines what container to load the properties from the store into. The DynamicDataStoreSession is a generic class so the Type you pass as a generic argument is used in all cases where needed. E.g.
var session = new DynamicDataStoreSession<Person>(); var people = from person in session.Items where person.FirstName == "Jones" select person;
- Find requires no magic strings - The Find method of the DynamicDataStore takes a string property name and value (or collection of). Some people quite rightly don't like using 'magic' strings in this way. The DynamicDataStoreSession provides a Find method where property names can be specified by using a lambda expression (thanks to Anders Hattestad for this). It also has a LINQ style method chaining syntax. E.g.
var session = new DynamicDataStoreSession<Person>(); var people = session.Find() .Where(p => p.LastName) .Equals("Jones") .And(p => p.FirstName) .Equals("Mark") .Go();
- IoC / Mocking / Unit Testing - The DynamicDataStoreSession and associated find classes implement interfaces. They also allow constructor injection of a DynamicDataStoreFactory
DynamicDataStoreUnitOfWork
It has always been possible to implement ‘unit of work’ / transactions between DDS stores and external data sources. The DynamicDataStoreUnitOfWork class wraps this functionality up nicely and should be used like a TransactionScope in a using block.
class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
public Identity AddressId { get; set; }
}
public class Address
{
public string Line1 { get; set; }
public string Line2 { get; set; }
public string City { get; set; }
}
using (var work = new DynamicDataStoreUnitOfWork())
{
var addressSession = work.GetSession<Address>();
var addressId = addressSession.Save(new Address()
{
Line1 = "Main Street",
City = "Chicago"
});
var personSession = work.GetSession<Person>();
personSession.Save(new Person()
{
FirstName = "Paul",
LastName = "Smith",
AddressId = addressId
});
work.Complete();
}
You can get an assembly here or if you want the source code then download the EPiServer.Extensions.DynamicDataStore.1.0.nupkg from nuget.episerver.com.
Comments