Let thinking be a continuous function.

Mar 09, 2014

ReliableUnitOfWork.SqlAzure v0.4.0 released

What is it?

It’s a light-weight implementation of UnitOfWork pattern. I found all published solution aren’t really transactional & mix between the role of Repository & the role of the UnitOfWork itself. Recently, Rob Conery explained this in a very good way here. He offered other solutions to avoid this broken non-transactional UoW kind of implementation.

Why I did this?

I didn’t build this just because I needed to build a better implementation. I was refactoring a legacy web application to be ready to be published on Windows Azure. The problem was that the application had an architectural anti-pattern, Transactional Integration. It was built depending on heavy usage of TransactionScope almost everywhere. Scopes were its unit of work to integrate any two components or types, not only services! Since that this project has a limited time, so building from scratch with proper architecture & design isn’t an option. So I needed to find a new way to define unit of work that can accommodate both business & database transactions/layers. At the same time, it was built with Linq2SQL! Decision was made to move Entity Framework 6 since that we are going to use Windows Azure SQL Databases (SQL Azure). We needed to benefit from its new Connection Resilience feature. At the same time, EF6 + SqlAzureExecutionStrategy doesn’t accept the use of TransactionScope or any form of user provided transaction, list of limitation here. Which means clearing all TransactionScope statements from solution otherwise it won’t work on cloud. Because of the design of the application, there’s a need to share a UoW between different components so they can run in context of a single transaction without wrapping them in one TransactionScope.

What is in ReliableUnitOfWork.SqlAzure?

This the solution for my problem & I think it can help in other different scenarios when you need to share different component in one transaction. The solution is based on wrapping a DbContext instance in a UnitOfWork instance and provides generic way of passing this it to different players who are going to share in this unit until it disposed. There are 3 ways to make use of this.

Before talking about this way, what are changes do you need to implement in your current EF-based solution to benefit from this implementation? Almost nothing serious, you need to inherit from type UnitDbContext. I’ll use snippets from Contoso University, the Microsoft sample for MVC5 & EF6. It needs long time to convert the whole solution to use this implementation so I’ll just try to explain how anyone can achieve this.

The first way is the simplest that almost doesn't give something new. It enables you to create a new UoW where you're going to directly access the DbContext inside it to perform anything you need. So it's just a mechanism to get a fresh DbContext when you need it & dispose it immediately after using it.

The above example makes use of UnitOfWorkFactory directly with shortest overload of StartNew().

You may think that for one of the controllers that has many Read-Only Action, it could be suitable to create a single UoW in controller’s constructor & dispose it while disposing the controller. Just make sure you name it differently, like _readOnlyUnitOfWork, so you don’t use it to persist something unintentionally. Later, I’m thinking to add the feature of to create ReadOnlyUnitOfWork that overrides SaveChanges() & SaveChangesAsync() to throw exception when someone unintentionally call them.

To see how you can save changes, see the next snippet. It's just straight forward.

Way Two, using UnitOfWorkFactory with Repository & DomainService abstract classes.

In other scenarios, you may need to build your own repositories & aggregates & domain services, if you have a rich domain. Let’s say we need to build StudentRepository & CourseRepository & DepartementRepository & CatalogueService. The CatalogueService will consume mentioned repositories to perform different tasks, so you need a way to share the DbContext between them & make sure to SaveChanges() in a single Transaction.

The implementation has the concept of UnitOfWorkPlayer, and also Repository which inherits from UnitOfWorkPlayer. When create a new UoW using StartNew() method in UnitOfWorkFactory you can pass all CatalogueService dependencies so you get a UoW that's aware of all of them & take their changes via a single instance of UnitDbContext. Types that inherits from UnitOfWorkPlayer are required to implement one method, the HandlePlayerJoinedUnit(). What for? if this type has also a dependency on types that inherit from UnitOfWorkPlayer it'll also join the same UoW. So the player isn't a must to be a repository only. It could be another type, like RiskCalculator, that needs access to UoW and/or other repositories to perform some task as part of a wider context.

I believe it's getting more complex talking about it & a short sample should be clearer than talk.

At this point, I'll fake up some example to show how to write the code until I got more time to write a complete scenario. Initially, this is how we can define skeleton of our repositories.

I ripped this, without tests & examples, from a real-world solution after I read Rob's article that I liked too much & I hope that this implementation avoided some of mentioned pitfalls & hopefully doesn't introduced any new pitfalls :) Later on, as soon as I have a chance, I'll add a complete example of how it works for me. What's available online now is GitHub repository here and a NuGet package here.

Comments

ReliableUnitOfWork.SqlAzure v0.4.0 released

What is it?

It’s a light-weight implementation of UnitOfWork pattern. I found all published solution aren’t really transactional & mix between the role of Repository & the role of the UnitOfWork itself. Recently, Rob Conery explained this in a very good way here. He offered other solutions to avoid this broken non-transactional UoW kind of implementation.

Why I did this?

I didn’t build this just because I needed to build a better implementation. I was refactoring a legacy web application to be ready to be published on Windows Azure. The problem was that the application had an architectural anti-pattern, Transactional Integration. It was built depending on heavy usage of TransactionScope almost everywhere. Scopes were its unit of work to integrate any two components or types, not only services! Since that this project has a limited time, so building from scratch with proper architecture & design isn’t an option. So I needed to find a new way to define unit of work that can accommodate both business & database transactions/layers. At the same time, it was built with Linq2SQL! Decision was made to move Entity Framework 6 since that we are going to use Windows Azure SQL Databases (SQL Azure). We needed to benefit from its new Connection Resilience feature. At the same time, EF6 + SqlAzureExecutionStrategy doesn’t accept the use of TransactionScope or any form of user provided transaction, list of limitation here. Which means clearing all TransactionScope statements from solution otherwise it won’t work on cloud. Because of the design of the application, there’s a need to share a UoW between different components so they can run in context of a single transaction without wrapping them in one TransactionScope.

What is in ReliableUnitOfWork.SqlAzure?

This the solution for my problem & I think it can help in other different scenarios when you need to share different component in one transaction. The solution is based on wrapping a DbContext instance in a UnitOfWork instance and provides generic way of passing this it to different players who are going to share in this unit until it disposed. There are 3 ways to make use of this.

Before talking about this way, what are changes do you need to implement in your current EF-based solution to benefit from this implementation? Almost nothing serious, you need to inherit from type UnitDbContext. I’ll use snippets from Contoso University, the Microsoft sample for MVC5 & EF6. It needs long time to convert the whole solution to use this implementation so I’ll just try to explain how anyone can achieve this.

The first way is the simplest that almost doesn't give something new. It enables you to create a new UoW where you're going to directly access the DbContext inside it to perform anything you need. So it's just a mechanism to get a fresh DbContext when you need it & dispose it immediately after using it.

The above example makes use of UnitOfWorkFactory directly with shortest overload of StartNew().

You may think that for one of the controllers that has many Read-Only Action, it could be suitable to create a single UoW in controller’s constructor & dispose it while disposing the controller. Just make sure you name it differently, like _readOnlyUnitOfWork, so you don’t use it to persist something unintentionally. Later, I’m thinking to add the feature of to create ReadOnlyUnitOfWork that overrides SaveChanges() & SaveChangesAsync() to throw exception when someone unintentionally call them.

To see how you can save changes, see the next snippet. It's just straight forward.

Way Two, using UnitOfWorkFactory with Repository & DomainService abstract classes.

In other scenarios, you may need to build your own repositories & aggregates & domain services, if you have a rich domain. Let’s say we need to build StudentRepository & CourseRepository & DepartementRepository & CatalogueService. The CatalogueService will consume mentioned repositories to perform different tasks, so you need a way to share the DbContext between them & make sure to SaveChanges() in a single Transaction.

The implementation has the concept of UnitOfWorkPlayer, and also Repository which inherits from UnitOfWorkPlayer. When create a new UoW using StartNew() method in UnitOfWorkFactory you can pass all CatalogueService dependencies so you get a UoW that's aware of all of them & take their changes via a single instance of UnitDbContext. Types that inherits from UnitOfWorkPlayer are required to implement one method, the HandlePlayerJoinedUnit(). What for? if this type has also a dependency on types that inherit from UnitOfWorkPlayer it'll also join the same UoW. So the player isn't a must to be a repository only. It could be another type, like RiskCalculator, that needs access to UoW and/or other repositories to perform some task as part of a wider context.

I believe it's getting more complex talking about it & a short sample should be clearer than talk.

At this point, I'll fake up some example to show how to write the code until I got more time to write a complete scenario. Initially, this is how we can define skeleton of our repositories.

I ripped this, without tests & examples, from a real-world solution after I read Rob's article that I liked too much & I hope that this implementation avoided some of mentioned pitfalls & hopefully doesn't introduced any new pitfalls :) Later on, as soon as I have a chance, I'll add a complete example of how it works for me. What's available online now is GitHub repository here and a NuGet package here.