您的位置:首页 > 其它

TinyFrame升级之七:重构Repository和Unit Of Work

2014-04-17 17:09 393 查看
首先,重构的想法来源于以下文章:CorrectuseofRepositoryandUnitOfWorkpatternsinASP.NETMVC,因为我发现在我的框架中,对UnitOfWork使用了错误的设计方法,同时感谢一下文章:GenericallyImplementingtheUnitofWork&RepositoryPatternwithEntityFrameworkinMVC&SimplifyingEntityGraphs,我的重构设计参考了它。

下面来说说我的具体重构方式。

在原来的代码中,我的Repository<T>泛型继承自IRepository<T>并且在增删改查代码中做了如下处理:

publicvirtualvoidInsert(Tentity)

[code]{
try

{

if(entity==null)

thrownewArgumentException("实体类为空");

DbSet.Add(entity);

context.SaveChanges();

}

catch(DbEntityValidationExceptiondbex)

{

varmsg=string.Empty;

foreach(varvalidationErrorsindbex.EntityValidationErrors)

foreach(varvalidateionErrorinvalidationErrors.ValidationErrors)

msg+=string.Format("Property:{0}Error:{1}",validateionError.PropertyName,validateionError.ErrorMessage);


varfail=newException(msg,dbex);

throwfail;

}

}

[/code]

最关键的地方是,我添加了“Context.SaveChanges”方法,这就直接导致UnitOfWork的规则失效。UnitOfWork出现的本身是为了提供事务提交支持。这样直接在Repository中提交,直接导致UnitOfWork功能废弃。

还有个地方就是在前台,通过Autofac注册完毕后,我是这么用的:


publicBookService(IUnitOfWorkunitOfWork

[code],IBookbookRepository
,IBookTypebookTypeRepository

,IBookPlacebookPlaceRepository

,ICacheManagercacheManager

,ILoggerServicelogger

)

{

this.unitOfWork=unitOfWork;

this.bookRepository=bookRepository;

this.bookTypeRepository=bookTypeRepository;

this.bookPlaceRepository=bookPlaceRepository;

this.cacheManager=cacheManager;

this.logger=logger;

}


privatereadonlyIUnitOfWorkunitOfWork;

privatereadonlyIBookbookRepository;

privatereadonlyIBookTypebookTypeRepository;

privatereadonlyIBookPlacebookPlaceRepository;

privatereadonlyICacheManagercacheManager;

privatereadonlyILoggerServicelogger;

[/code]

这样做的话,当以后我们有表删除或者新增的时候,我们不得不维护这样的列表。这完全不符合OO设计原则。

但是如果引入UnitOfWork的话,内部利用Hashtable等实现对Respository的指向,那么在界面我们只要这样写就可以了:


publicBookService(

[code]IUnitOfWorkunitOfWork
,ICacheManagercacheManager

,ILoggerServicelogger

)

{

this.unitOfWork=unitOfWork;

this.cacheManager=cacheManager;

this.logger=logger;

}


privatereadonlyIUnitOfWorkunitOfWork;

privatereadonlyICacheManagercacheManager;

privatereadonlyILoggerServicelogger;

[/code]

使用的时候,直接这样实例化就行了:


varbookPlaceRepository=unitOfWork.Repository<BookPlace>();



这样做完全不用顾虑有新表的添加删除了。代码根本就不用动。

所以,综上两点,UnitOfWork的引入为了解决以下问题:

1.提供全局事务支持。

2.提供对Repository模型的指向。以便于松耦合绑定。

下面是代码重构部分:

IUnitOfWork接口部分:


usingSystem;

[code]usingTinyFrame.Data.DataRepository;
usingTinyFrame.Data.DomainModel;


namespaceTinyFrame.Unitofwork

{

publicinterfaceIUnitOfWork

{

voidCommit();

IRepository<T>Repository<T>()whereT:class;


voidDispose(booldisposing);

voidDispose();

}

}

[/code]

实现部分比较简单,利用Hashtable来保存对Repository的指向:


usingSystem;

[code]usingSystem.Data.Entity;
usingTinyFrame.Data.DataRepository;

usingTinyFrame.Data.DomainModel;

usingTinyFrame.Data.DataContext;

usingSystem.Collections;


namespaceTinyFrame.Unitofwork

{

publicclassUnitOfWork:IUnitOfWork

{

publicUnitOfWork(IDbContextdbContext)

{

this.dbContext=dbContext;

}


privatereadonlyIDbContextdbContext;

privatebooldisposed;

privateHashtablerepositorys;


publicvoidCommit()

{

dbContext.SaveChanges();

}


publicIRepository<T>Repository<T>()whereT:class

{

if(repositorys==null)

repositorys=newHashtable();


vartype=typeof(T).Name;


if(!repositorys.ContainsKey(type))

{

varrepositoryType=typeof(Repository<>);

varrepositoryInstance=Activator.CreateInstance(repositoryType.MakeGenericType(typeof(T)),dbContext);

repositorys.Add(type,repositoryInstance);

}

return(IRepository<T>)repositorys[type];

}


#regionDisposemethod

publicvirtualvoidDispose(booldisposing)

{

if(!disposed)

if(disposing)

dbContext.Dispose();

disposed=true;

}


publicvoidDispose()

{

Dispose(true);

GC.SuppressFinalize(this);

}

#endregion

}

}

[/code]

第17行,保持对DbContext的引用,以便于进行提交操作。

第26行,Repository<T>泛型方法,以便于动态返回仓储模型。

需要注意的是,在Repository<T>的实现中,不要再增删改查里面再添加DbContext.SaveChanges方法,首先是没意义,其次是完全不符合Repository和UnitOfWork的做法。

最后附图一张,表明我对Repository和UnitOfWork的理解:





本章源码下载:

点击这里下载

备份下载地址
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: