c# - Refactoring code using Entity Framework 6 to follow TDD -


right now, i'm on task refactor asp.net mvc application using ef6. currently, code use ef designer generate entities (edmx file) , of logic bloated controller.

i've read article tdd , ef6, , know question similar others like

but of refer "code first" development. i'm aware ef6 has implement unitofwork internally, question how structure code will:

  • follow tdd practice (testable code)
  • moving of logic layer controllers

but still using "database first" development type. pattern should follow? of feedback appreciate.

[edited] 1 of action in current controller (right contain 500+ line of code)

public actionresult toggleproductpromocodeisactive(string promocode, string productid, string countrycode)     {         var isactive = toggleproductpromocodeisactive(promocode, productid, countrycode);         return json(new { isactive = isactive }, jsonrequestbehavior.allowget);     }  public actionresult addpromocodeproperties(string promocode, datetime beginningdatetime, datetime enddatetime, bool isactive, int? length, string countrycode, short? maximumrenewals)     {         int id = addpromocodeproperties(promocode, beginningdatetime, enddatetime, isactive, length, countrycode, maximumrenewals);         if (id != 0)         {             return json(new { message = "promo code properties have been succesfully added", id = id, promocode = promocode }, jsonrequestbehavior.allowget);         }         else         {             return json(new { message = "failed: same promo code same country code has existed", promocode = promocode }, jsonrequestbehavior.allowget);         }     }       // ----- line of code      private int addproductpromocode(string promocode, double discountpercentage, string productid, bool isactive, string countrycode, string paymentpagetext, string finalproductid)     {         using (var provisioningcontext = new provisioningentities())         {             var productpromocode = provisioningcontext.productpromocodes.singleordefault(x => x.code == promocode && x.productid == productid && x.countrycode == countrycode);             if (productpromocode == null)             {                 try                 {                     productpromocode = new productpromocode();                     productpromocode.code = promocode;                     productpromocode.discountpercentage = discountpercentage;                     productpromocode.productid = productid;                     productpromocode.isactive = isactive;                     productpromocode.countrycode = countrycode;                     productpromocode.paymentpagetext = paymentpagetext;                     productpromocode.finalproductid = finalproductid;                     provisioningcontext.productpromocodes.add(productpromocode);                     provisioningcontext.savechanges();                     return productpromocode.id;                 }                 catch                 {                     return 0;                 }             }             else             {                 return 0;             }         }     }      private bool toggleproductpromocodeisactive(string promocode, string productid, string countrycode)     {         using (var provisioningcontext = new provisioningentities())         {             var productpromocode = provisioningcontext.productpromocodes.singleordefault(x => x.code == promocode && x.productid == productid && x.countrycode == countrycode);             productpromocode.isactive = !productpromocode.isactive;             provisioningcontext.entry(productpromocode).state = entitystate.modified;             provisioningcontext.savechanges();             return productpromocode.isactive;         }     } 

this do:

implement repository each entity in context. if have set of similar operations done entities (for example, getall, getbyid, create, update, delete), define common interface starting point. then, repositories implement own interface inherit one. use generics accomplish this:

public interface ibaserepository<t> {     t getbyid(int id);     ienumerable<t> getall();     void create(t element);     // , on... } 

this provide couple of advantages:

1) centralize more important operations in base interface, , each repository interface inherit one.

2) since repositories implement own interfaces, can create mock implementations tdd.

3) can decouple interface actual implementations , implement dependency injection. there ton of ioc containers easy use. use microsoft's unity, easy use (for example, in unity can solve type implements interface through web.config or app.config).

so @ point have data access layer divided following components:

  • database context (where set dbsets, configurations, mappings, seeds)
  • repositories (the actual implementations use dbcontext)
  • repositories interfaces (that treat actual contracts operate database).
  • mock repositories

for second part, have elaborate more bloated logic in controllers, since actions , methods having responsibility in hands. info provided, suggest follow s.o.l.i.d. principles.

edit:

now see code pasted.

in particular example provided, implementing repository productpromocodesentity take logic related deal entity out of controller repository , data provider layers.

first, define repo interface (since see these operations need in provisioningcontext

public interface iproductpromocoderepository {     // can see these similar methods ibaserepository interface defines, can make 1 inherit it.     productpromocode get(string code, string id, string country);     void create(productpromocode item);     void update(productpromocode item); } 

then, write implementation (a class called productpromocoderepository inherits repository interface). code of each of these methods more or less in private methods of controller, , provisioningcontext member of class implements them, controller needs deal productpromocoderepository.

you can encapsulate logic

productpromocode.isactive = !productpromocode.isactive; provisioningcontext.entry(productpromocode).state = entitystate.modified; provisioningcontext.savechanges(); 

in own method in repository if want, in controller need use value method returns.

after that, these 2 actions following:

public actionresult toggleproductpromocodeisactive(string promocode, string productid, string countrycode) {     var isactive = _productpromocoderepository.toogleactive(promocode, productid, countrycode);// encapsulates 3 lines of code above...     return json(new { isactive = isactive }, jsonrequestbehavior.allowget); }  public actionresult addpromocodeproperties(string promocode, datetime beginningdatetime, datetime enddatetime, bool isactive, int? length, string countrycode, short? maximumrenewals) {     var productpromocode = _productpromocoderepository.get(promocode, productid/*i don't know value*/, countrycode);     if(productpromocode != null)         return json(new { message = "failed: same promo code same country code has existed", promocode = promocode }, jsonrequestbehavior.allowget);      productpromocode = new productpromocode();     productpromocode.code = promocode;     productpromocode.discountpercentage = discountpercentage;     productpromocode.productid = productid;     productpromocode.isactive = isactive;     productpromocode.countrycode = countrycode;     productpromocode.paymentpagetext = paymentpagetext;     productpromocode.finalproductid = finalproductid;     _productpromocoderepository.create(productpromocode);     // can move these lines above repo overload create method takes parameters.      // here can sure item didn't exist before in database, have deal errors in creation , return proper error message.     return json(new { message = "promo code properties have been succesfully added", id = productpromocode.id, promocode = productpromocode.code }, jsonrequestbehavior.allowget);  } 

Comments

Popular posts from this blog

Email notification in google apps script -

c++ - Difference between pre and post decrement in recursive function argument -

javascript - IE11 incompatibility with jQuery's 'readonly'? -