介紹

主要用來管理物件的CRUD操作,Unit of Work負責協調這些變化的持久化工作。Unit of Work的使用會結合Repository。接下來我們就開始來新增Unit of Work,在SQLModel新增UnitOfWork的資料夾,並新增UnitOfWork的介面和類別,如下圖:
CreateUnitOfWork

IUnitOfWork.cs

Unit of Work的介面,程式如下:

public interface IUnitOfWork : IDisposable
{
	DbContext Context { get; }

	int SaveChange();
}

UnitOfWork.cs

Unit of Work的實作,程式如下:

public class UnitOfWork : IUnitOfWork
{
	private IDbContextFactory _dbContextFactory { get; set; }

	private DbContext context;

	private bool disposed = false;

	public DbContext Context
	{
		get
		{
			if (this.context != null)
			{
				return this.context;
			}

			this.context = _dbContextFactory.GetDbContext();
			return this.context;
		}
	}

	public UnitOfWork(IDbContextFactory dbContextFactory)
	{
		this._dbContextFactory = dbContextFactory;
	}

	public int SaveChange()
	{
		int result = this.Context.SaveChanges();
		return result;
	}

	protected virtual void Dispose(bool disposing)
	{
		if (!this.disposed)
		{
			if (disposing)
			{
				this.Context.Dispose();
				this.context = null;
			}
		}
		this.disposed = true;
	}

	public void Dispose()
	{
		Dispose(true);
		GC.SuppressFinalize(this);
	}
}

修改GenericRpository

主要修改的程式如下:

public class GenericRepository<TEntity> : IRepository<TEntity>
        where TEntity : class 
{
	public IUnitOfWork _UnitOfWork { get; set; }
	
	private DbSet<TEntity> _dbSet { get; set; }
	
	public GenericRepository(IUnitOfWork unitOfWork)
	{
		this._UnitOfWork = unitOfWork;
		this._context = unitOfWork.Context;
		this._dbSet = unitOfWork.Context.Set<TEntity>();
	}
}

修改Service

主要修改的程式如下:

public class ProjectService : IProjectService
{
	private readonly IUnitOfWork _unitOfWork;
	
	private readonly IRepository<Project> _repository;

	public ProjectService(IUnitOfWork unitOfWork, IRepository<Project> repository)
	{
		this._unitOfWork = unitOfWork;
		this._repository = repository;
	}
	
	public void Create(Project entity)
	{
		if (entity == null)
		{
			throw new ArgumentNullException("entity");
		}
		else
		{
			_repository.Create(entity);
			_unitOfWork.SaveChange();
		}
	}

	public void Update(Project entity)
	{
		if (entity == null)
		{
			throw new ArgumentNullException("entity");
		}
		else
		{
			_repository.Update(entity);
			_unitOfWork.SaveChange();
		}
	}

	public void Delete(Guid id)
	{
		if (!IsExists(id))
		{

		}
		else
		{
			var entity = GetById(id);
			_repository.Delete(entity);
			_unitOfWork.SaveChange();
		}
	}
}

UnityConfig註冊

最後在UnitConfig加上註冊就好了,程式如下:

public static void RegisterTypes(IUnityContainer container)
{
	#region UnitOfWork
	container.RegisterType<IUnitOfWork, UnitOfWork>();
	#endregion
}

做到這裡會發現如果Service建的很多,每個Service都必須要重複寫CRUD,下一篇將把Service重複的地方抽出,並把Model會重複的部分也抽出。

參考資料:
http://kevintsengtw.blogspot.tw/2015/04/aspnet-mvc-twmvc18.html

程式碼已放上Github