In business, we involve the creation of objects, rebuilding, updating, destroying, and so on, which often need to be persisted into the database, and we use warehousing to achieve access to the data
1. First we want to implement the warehousing context, the warehousing context is primarily to maintain a number of created, updated, destroyed list of objects, in the future can achieve batch persistence, so as to maintain multi-entity and multi-aggregation transactions, so as to achieve internal consistency and external consistency:
usingOrder.Domain.Aggreate;usingOrder.Domain.Repository;usingSystem;usingSystem.Collections.Generic;usingSystem.Threading;namespaceorder.repositories{ Public Abstract classRepositorycontext:irepositorycontext, IDisposable {Private ReadOnlyGuid ContextID =Guid.NewGuid (); Private ReadOnlyThreadlocal<dictionary<guid,Object>> Localcreatedics =NewThreadlocal<dictionary<guid,Object>>(); Private ReadOnlyThreadlocal<dictionary<guid,Object>> Localupdatedics =NewThreadlocal<dictionary<guid,Object>>(); Private ReadOnlyThreadlocal<dictionary<guid,Object>> Localremovedics =NewThreadlocal<dictionary<guid,Object>>(); //the default all content in the collection is marked as committed Private ReadOnlythreadlocal<BOOL> localcommitted =Newthreadlocal<BOOL> (() =true); Public BOOLCommitted {Get{returnlocalcommitted. Value; } Set{localcommitted. Value =value;} } PublicGuid ContextID {Get{returnContextID;} } /// <summary> ///re-implemented by inheriting classes/// </summary> Public Abstract voidCommit (); Public Abstract voidRollBack (); Public Virtual voidDispose () {localcreatedics. Dispose (); Localupdatedics. Dispose (); Localremovedics. Dispose (); Localcommitted. Dispose (); } Public Virtual voidRegistercreate<taggreateroot> (Taggreateroot aggreateroot)whereTaggreateroot:class, Iaggreateroot {if(Aggreateroot. Id.equals (guid.empty))Throw NewArgumentException ("Object ID is empty"); if(localcreatedics. Value.containskey (Aggreateroot. ID))Throw NewInvalidOperationException ("This object is already in the Create collection"); Localcreatedics. Value.add (Aggreateroot. Id, Aggreateroot); //the created object is added to the collection, and the set status is uncommittedLocalcommitted. Value =false; } Public Virtual voidRegisterremove<taggreateroot> (Taggreateroot aggreateroot)whereTaggreateroot:class, Iaggreateroot {if(Aggreateroot. Id.equals (guid.empty))Throw NewArgumentException ("Object ID is empty"); if(localremovedics. Value.containskey (Aggreateroot. ID))Throw NewInvalidOperationException ("This object is already in the Delete collection"); if(localupdatedics. Value.containskey (Aggreateroot. ID))Throw NewInvalidOperationException ("This object is being modified and cannot be added to the Delete collection"); Localremovedics. Value.add (Aggreateroot. Id, Aggreateroot); Localcommitted. Value=false; } Public Virtual voidRegisterupdate<taggreateroot> (Taggreateroot aggreateroot)whereTaggreateroot:class, Iaggreateroot {if(Aggreateroot. Id.equals (guid.empty))Throw NewArgumentException ("Object ID is empty"); if(localupdatedics. Value.containskey (Aggreateroot. ID))Throw NewInvalidOperationException ("This object is already in the update collection"); if(localremovedics. Value.containskey (Aggreateroot. ID))Throw NewInvalidOperationException ("This object is being deleted and cannot be added to the update collection"); Localupdatedics. Value.add (Aggreateroot. Id, Aggreateroot); Localcommitted. Value=false; } }}
Because we end up using EF as the Object list state maintenance and finally committing to persisted storage, we implement a warehouse context for EF, using the EF mechanism to maintain and commit:
usingOrder.Domain.Model;usingSystem.Threading;usingSystem.Data.Entity;namespaceorder.repositories{ Public classEfrepositorycontext:repositorycontext {Private ReadOnlyThreadlocal<orderscontainer> Orderdbcontext =NewThreadlocal<orderscontainer> (() =NewOrderscontainer ()); PublicDbContext Orderdbcontext {Get{returnOrderdbcontext. Value; } } Public Override voidRegistercreate<taggreateroot>(Taggreateroot aggreateroot) {Orderdbcontext. Value.set<TAggreateRoot>(). ADD (Aggreateroot); Committed=false; } Public Override voidRegisterupdate<taggreateroot>(Taggreateroot aggreateroot) {Orderdbcontext. Value.entry<TAggreateRoot> (Aggreateroot). State =entitystate.modified; Committed=false; } Public Override voidRegisterremove<taggreateroot>(Taggreateroot aggreateroot) {Orderdbcontext. Value.set<TAggreateRoot>(). Remove (Aggreateroot); Committed=false; } Public Override voidCommit () {if(!Committed) Orderdbcontext. Value.savechanges (); Committed=true; } Public Override voidRollBack () {Committed=false; } Public Override voidDispose () {if(!Committed) Commit (); Orderdbcontext. Value.dispose (); Orderdbcontext. Dispose (); Base. Dispose (); } }}
2. Then we want to implement warehousing, warehousing, mainly for object creation, reconstruction, update and destruction, which create, update and destroy through the warehousing context to achieve batch persistence:
usingOrder.Domain.Aggreate;usingOrder.Domain.Repository;usingSystem;usingSystem.Collections.Generic;usingSystem.Linq;usingSystem.Linq.Expressions;usingSystem.Data;namespaceorder.repositories{ Public Abstract classEfrepository<taggreateroot>: efrepositorycontext,irepository<taggreateroot>whereTaggreateroot:class, Iaggreateroot { Public voidCreate (Taggreateroot aggreateroot) {Base. Registercreate<taggreateroot>(Aggreateroot); } PublicList<taggreateroot> getbycondition (Expression<func<taggreateroot,BOOL>>condition) { returnOrderdbcontext.set<taggreateroot>() . Where (condition). ToList (); } Publictaggreateroot GetbyId (Guid id) {returnOrderdbcontext.set<taggreateroot>(). Where (P=>p.id==ID). Singleordefault (); } Public voidRemove (Taggreateroot aggreateroot) {Base. Registerremove<taggreateroot>(Aggreateroot); } Public voidRemovebyid (Guid id) {varAggreateroot = orderdbcontext.set<taggreateroot>(). Where (P= = P.id = =ID). Singleordefault (); Remove (Aggreateroot); } Public voidUpdate (Taggreateroot aggreateroot) {Base. Registerupdate<taggreateroot>(Aggreateroot); } }}
Storage top-level implementation of domain-driven design cases