entity framework and a generic repository.docx
TRANSCRIPT
-
8/9/2019 Entity Framework and a Generic Repository.docx
1/9
Entity Framework and a Generic ReposIntroduction
This article presents a high-level overview of multi-layered.Net application that implements the Repository Patternalong with the Entity Framework on its ata !ccess layer.
The application uses "nversion of #ontrol to decouplea$stractions %interfaces& from implementations.'ore speci(cally) it uses Nin*ect to implementependency "n*ection.
This separation of concerns allows us to dissect modulesand swap them with other implementations. This isachieved $y relying on contracts rather than
implementations which results on code that is agnostic ofhow operations are implemented $ehind the interfaces.
For e+ample) if you design your $usiness logic to rely onan interface that follows the Repository Pattern as adata persistence mechanism) for all intends and purposes)your $usiness logic will treat this dependency as amemory domain o$*ect collection. Therefore) forproduction you could provide an implementation of that
dependency that uses the Entity Framework $ehind thescenes to store and retrieve data from a , data$ase. Forautomated unit testing) you could provide a completelydi/erent implementation that stores and retrieves datafrom in-memory o$*ects.
Evidently) you could e+ecute all your tests against thedata$ase0 however) this setting greatly helps isolating unittests and cut dependencies on other resources) such as
the data$ase) which may need more work to setup up andtear up for unit testing %especially true if you have otherteam mem$ers&.
1efore moving forward) make sure you read 2hat3s"nversion of #ontrol4if you are not familiar with "nversionof #ontrol or ependency "n*ection or would like to hearmore a$out the advantages of interface-$ase design
Note5 This article does not get into details on how to useall these technologies and patterns) instead it provides
http://www.megustaulises.com/2013/03/entity-framework-and-generic-repository.htmlhttp://www.megustaulises.com/2012/12/what-is-inversion-of-control.htmlhttp://www.ninject.org/http://www.megustaulises.com/2012/12/what-is-inversion-of-control.htmlhttp://www.megustaulises.com/2012/12/what-is-inversion-of-control.htmlhttp://www.megustaulises.com/2012/12/what-is-inversion-of-control.htmlhttp://www.ninject.org/http://www.megustaulises.com/2012/12/what-is-inversion-of-control.htmlhttp://www.megustaulises.com/2012/12/what-is-inversion-of-control.htmlhttp://www.megustaulises.com/2013/03/entity-framework-and-generic-repository.html -
8/9/2019 Entity Framework and a Generic Repository.docx
2/9
references to other sources and shows you how they all (ttogether in a single application.
The Repository Pattern
The Repository Pattern6mediates $etween the domainand data mapping layers using a collection-like interfacefor accessing domain o$*ects6.
"n a multi-layered application the Repository Pattern isimplemented in the ata !ccess layer%or Persistence ayer& and it interacts with the ,erviceayer and the ata ,ource $y mapping data to o$*ects
$ack and forth. The following picture shows a we$application that uses a , data$ase in the $ack end.
For each repository in the application we will create $oththe interface and the implementation. The interface willhave methods such as5 !dd) elete) Find) Get!ll) etc. 'ostmethods will return o$*ects or collections) others such as#ount will return integers. For e+ample) the Get!ll method
for the 7ser3s Repository will return the list of all 7ser3so$*ects found in the data$ase.
http://martinfowler.com/eaaCatalog/repository.htmlhttp://martinfowler.com/eaaCatalog/repository.html -
8/9/2019 Entity Framework and a Generic Repository.docx
3/9
-
8/9/2019 Entity Framework and a Generic Repository.docx
4/9
?@8A88
898:8;88?8@9A
98999:9;99?9@
:A:8:9:::;::?:@;A;8;9;:;;;;?;@
D get0 set0
publicGenericRepository%"$#onte+tFactory d$#onte+tFactory D
#onte+t d$#onte+tFactory.Get$#onte+t%&0log og'anager.Getogger%GetType%&&0
publicvirtual"uerya$leBtC Get!ll%& D return#onte+t.,etBtC%&0
publicvirtual"uerya$leBtC Find!ll1y%,ystem.inH.E+pressio
D return#onte+t.,etBtC%&.2here%predicate&0
publicvirtualT FindFirst1y%,ystem.inH.E+pressions.E+pressio D return#onte+t.,etBtC%&.FirstIrefault%predicate&0
publicvirtualvoid!dd%T entity& D #onte+t.,etBtC%&.!dd%entity&0
publicvirtualvoidelete%T entity& D
#onte+t.,etBtC%&.Remove%entity&0
publicvirtualvoidelete%"uerya$leBtC entities& D foreach%T entity inentities.Toist%&& #onte+t.,etBtC%&.Remove%entity&0
publicvirtualvoidEdit%T entity& D #onte+t.Entry%entity&.,tate ,ystem.ata.Entity,tate.'odi(e
-
8/9/2019 Entity Framework and a Generic Repository.docx
5/9
???@@A@8
publicvirtualint,ave%&
D try
D return#onte+t.,ave#hanges%&0 catch%$EntityJalidationE+ception d$E+& D foreach%var validationErrors ind$E+.EntityJalidationErrors& D foreach%var validationError invalidationErrors.JalidationE D
log.Error%string.Format%6Property5 DA Error5 D86) validati catch%E+ception e+& D log.Error%6,ave failed6) e+&0 returnA0
publicvirtualT Find%intid&
D return#onte+t.,etBtC%&.Find%id&0
publicvoidRefresh%T entity& D #onte+t.Entry%entity&.Reload%&0
publicvirtualint#ount%& D return#onte+t.,etBtC%&.#ount%&0
publicvoidispose%& D if%#onte+t K null&
-
8/9/2019 Entity Framework and a Generic Repository.docx
6/9
@9@:@;
#onte+t.ispose%&0
UsageThis is how you would declare your interface. Notice that$esides declaring the common code %!dd) elete) Get!ll)etc.& it also declares and additional method speci(c to thisrepository Get,u$ordinates%&4
89:
;
publicinterface"EmployeeRepository 5"GenericRepositoryBemploD"Enumera$leBemployeeC Get,u$ordinates%intid&0
Lere is the implementation) notice the constructor isneeded here in order to o$tainan "$#onte+tFactory instance through ependency"n*ection. Evidently) the class must also implementGet,u$ordinates%&) this was *ust a simple e+ample on howyou can leverage the generic repository class and you arestill a$le to introduce class-speci(c code.4
89:;?
@8A88
publicclassEmployeeRepository 5 GenericRepositoryBemployeD publicEmployeeRepository%"$#onte+tFactory d$#onte+tFactor 5 base%d$#onte+tFactory& D public"Enumera$leBemployeeC Get,u$ordinates%intid&
D
return%#onte+t asata'odel#ontainer&.Get,u$ordinates%id&0
Sharing the DbContet ob!ect by using aDbContect"actory
The "$#onte+tFactory interface is very straightforward) itonly declares a method and implements the "isposa$leinterface.
4
-
8/9/2019 Entity Framework and a Generic Repository.docx
7/9
89:;
publicinterface"$#onte+tFactory 5 "isposa$leD $#onte+t Get$#onte+t%&0
The implementation is also straightforward. The1#onte+tFactory creates an instance of $#onte+t in itsconstructor. For this reason) we can use the factory classto o$tain an instance of $#onte+t and as long as we usethe same factory we will $e sharing thesame $#onte+t instance across all repositories. This isactually very easy to do with a dependency in*ectioncontainer such as Nin*ect%$rieMy descri$ed in the ne+t
section&.489:;?@8A88898:8;8
8?8@9A98999:
publicclass$#onte+tFactory 5 "$#onte+tFactoryD privatereadonly$#onte+t conte+t0public$#onte+tFactory%&
Dconte+t ne#ata'odel#ontainer%&0
public$#onte+t Get$#onte+t%&
D returnconte+t0 publicvoidispose%&
D if%conte+t K null&
D conte+t.ispose%&0 G#.,uppressFinalie%this&0
Using Nin!ect as The IoC ContainerNin*ectis very simple to setup. "n a few words you need to
add a few dependencies to your pro*ect and a couple of
http://www.ninject.org/http://www.ninject.org/http://www.ninject.org/http://www.ninject.org/ -
8/9/2019 Entity Framework and a Generic Repository.docx
8/9
con(guration (les. The interesting piece is where you tellthe container the in*ection patternit will use %e.g.) in*ectdependencies through setters or constructors& and alsohow to map $etween interfaces and implementations. For
e+ample) the Nin*ect2e$#ommon class provides thefollowing method to do this mapping54
89:;?@8A88898:
OOO BsummaryCOOO oad your modules or register your services hereKOOO BOsummaryCOOO Bparam name6kernel6CThe kernel.BOparamCprivatestaticvoidRegister,ervices%"ernel kernel&D OOrepoositories kernel.1indBid$conte+tfactoryC%&.ToBd$conte+tfactoryC%&."nReH kernel.1indBiemployeerepositoryC%&.ToBemployeerepositoryC%&0OO... more repositories...
Ine thing to note is the use of the ReHuest scope for the$#onte+tFactory class which tells Nin*ect to create asingle instance of this o$*ect per LTTP reHuest. "n otherwords) every time a user reHuests a page) no mater howmany repository classes are involved) Nin*ect will create asingle factory class and) therefore) asingle $#onte+t instance. This also ensures that theo$*ect is destroyed once the reHuest completes. Goodstu/..
Note5 "n the e+amples provided here "3ve $een usingdependency in*ection through constructors.
Putting it all together $ Using theRepositoriesNow that you have created repositories you could eitheruse them directly on your controllers or on a service class.
The following e+ample shows the Employee ,erviceo$taining the repositories from the ependency "n*ectioncontainer.
4
https://github.com/ninject/ninject/wiki/Injection-Patternshttps://github.com/ninject/Ninject.Web.Common/wiki/InRequestScopehttps://github.com/ninject/ninject/wiki/Injection-Patternshttps://github.com/ninject/Ninject.Web.Common/wiki/InRequestScope -
8/9/2019 Entity Framework and a Generic Repository.docx
9/9
89:;
?@8A88898:
8;8