Unit of Work Pattern

Posted by Kamarudin • 1 minute read • 2 Comments

Kalau sudah membahas Repository Pattern rasanya kurang manteb jika tidak membahas Unit of Work Pattern, dua pattern ini biasanya sering digunakan secara bersamaan. Kata emak-emak “ibarat sop ayam tanpa garam, rasanya hambar” he he :grin:

Unit of Work Pattern digunakan untuk mengelompokan satu atau beberapa operasi (biasanya operasi CRUD) ke dalam satu kesatuan transaksi. Jika salah satu operasi gagal, yang lain juga harus dibatalkan. Jadi cara kerja Unit of Work Pattern ini mirip dengan salah satu fitur andalan DBMS yaitu transaction.

Unit of Work Pattern sendiri merupakan salah satu pattern kesukaan Microsoft, ini bisa dilihat dari salah satu produk open source Microsoft yang menggunakan pattern ini yaitu Entity Framework. Bagi Anda yang sudah pernah mencoba Entity Framework mungkin sudah tidak asing lagi dengan class EF Context yang menggunakan Unit of Work Pattern.

Membuat Interface dan Class Konkret Unit of WorkPermalink

Sama seperti pembahasan Repository Pattern, impelmentasi Unit of Work Pattern juga disarankan menggunakan interface.

Berdasarkan contoh project Repository Pattern, kita akan menambahkan interface baru dengan nama IUnitOfWork. Di dalam interface ini kita membuat beberapa property dengan tipe interface repository.

Setelah itu kita buatkan class konkretnya dengan nama UnitOfWork, dan ingat class ini harus mengimplementasikan interface IUnitOfWork.

Terakhir kita lengkapi kode class UnitOfWork seperti berikut :

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Northwind.Repository.Api;
using System.Data;
namespace Northwind.Repository.Service
{
public class UnitOfWork : IUnitOfWork
{
private IDapperContext _context;
private IDbTransaction _transaction;
private ICategoryRepository _categoryRepository;
private IProductRepository _productRepository;
public UnitOfWork(IDapperContext context)
{
this._context = context;
}
public ICategoryRepository CategoryRepository
{
get { return _categoryRepository ?? (_categoryRepository = new CategoryRepository(_transaction, _context)); }
}
public IProductRepository ProductRepository
{
get { return _productRepository ?? (_productRepository = new ProductRepository(_transaction, _context)); }
}
public void BeginTransaction()
{
if (_transaction != null)
throw new NullReferenceException("Not finished previous transaction");
_transaction = _context.db.BeginTransaction();
}
public void Commit()
{
if (_transaction == null)
throw new NullReferenceException("Tryed commit not opened transaction");
_transaction.Commit();
}
}
}
view raw UnitOfWork.cs hosted with ❤ by GitHub
Testing Class Unit of WorkPermalink

Sebagai penutup kita akan melakukan tes sederhana dengan menggunakan aplikasi console. Dari hasil tes ini akan terlihat begitu mudahnya menerapkan konsep transaction menggunakan Unit of Work Pattern.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Northwind.Model;
using Northwind.Repository.Api;
using Northwind.Repository.Service;
namespace Northwind.ConsoleApp
{
class UnitOfWorkTest
{
static void Main(string[] args)
{
using (IDapperContext context = new DapperContext())
{
// buat objek unit of work
IUnitOfWork uow = new UnitOfWork(context);
var result = 0;
uow.BeginTransaction(); // mulai transaction
// buat objek category
var category = new Category
{
CategoryName = "Condiments",
Description = "Sweet and savory sauces, relishes, and seasonings"
};
result = uow.CategoryRepository.Save(category); // simpan data category
Console.WriteLine("Tambah data category {0}", result > 0 ? "berhasil" : "gagal");
// buat objek product
var product = new Product
{
CategoryID = category.CategoryID,
ProductName = "Genen Shouyu",
QuantityPerUnit = "24 - 250 ml bottles",
UnitPrice = 15.5,
UnitsInStock = 50
};
result = uow.ProductRepository.Save(product); // simpan data product
Console.WriteLine("Tambah data product {0}", result > 0 ? "berhasil" : "gagal");
uow.Commit(); // commit, simpan data secara permanen ke database
}
Console.WriteLine("\nPress any key to exit ...");
Console.ReadKey();
}
}
}

Selamat MENCOBA :blush:

Comments