c# - Clean Code: Readable Dependency Injection suggestions? -


i have project adds elements autocad drawing. noticed starting write same ten lines of code in multiple methods (only showing 2 simplicity).

initial implementation: notice thing changes adding line instead of circle.

[commandmethod("test", commandflags.session)]     public void test()     {         addlinetodrawing();         addcircletodrawing();     }      private void addlinetodrawing()     {         using (documentlock lockeddocument = application.documentmanager.mdiactivedocument.lockdocument())         {             using (database database = application.documentmanager.mdiactivedocument.database)             {                 using (transaction transaction = database.transactionmanager.starttransaction())//start transaction                 {                     //open block table read                     blocktable blocktable = transaction.getobject(database.blocktableid, openmode.forread) blocktable;                      //open block table record model space write                     blocktablerecord blocktablerecord = (blocktablerecord)transaction.getobject(blocktable[blocktablerecord.modelspace], openmode.forwrite);                      line line = new line(new point3d(0, 0, 0), new point3d(10, 10, 0));                     blocktablerecord.appendentity(line);                      transaction.addnewlycreateddbobject(line, true);                      transaction.commit();                 }             }         }     }      private void addcircletodrawing()     {         using (documentlock lockeddocument = application.documentmanager.mdiactivedocument.lockdocument())         {             using (database database = application.documentmanager.mdiactivedocument.database)             {                 using (transaction transaction = database.transactionmanager.starttransaction())//start transaction                 {                     //open block table read                     blocktable blocktable = transaction.getobject(database.blocktableid, openmode.forread) blocktable;                      //open block table record model space write                     blocktablerecord blocktablerecord = (blocktablerecord)transaction.getobject(blocktable[blocktablerecord.modelspace], openmode.forwrite);                      circle circle = new circle(new point3d(0, 0, 0), new vector3d(0, 0, 0), 10);                     blocktablerecord.appendentity(circle);                      transaction.addnewlycreateddbobject(circle, true);                      transaction.commit();                 }             }         }     } 

injection: approached removed duplication of code, think readability poor.

[commandmethod("test", commandflags.session)]     public void test()     {         performactiononblocktable(new circledrawer());         performactiononblocktable(new linedrawer());     }      public interface idraw     {         dbobject drawobject(blocktablerecord blocktablerecord);     }      public class circledrawer : idraw     {         public dbobject drawobject(blocktablerecord blocktablerecord)         {             circle circle = new circle(new point3d(0, 0, 0), new vector3d(0, 0, 0), 10);             blocktablerecord.appendentity(circle);              return circle;         }     }      public class linedrawer : idraw     {         public dbobject drawobject(blocktablerecord blocktablerecord)         {             line line = new line(new point3d(0, 0, 0), new point3d(10, 10, 0));             blocktablerecord.appendentity(line);              return line;         }     }      private void performactiononblocktable(idraw drawer)     {         using (documentlock lockeddocument = application.documentmanager.mdiactivedocument.lockdocument())         {             using (database database = application.documentmanager.mdiactivedocument.database)             {                 using (transaction transaction = database.transactionmanager.starttransaction())//start transaction                 {                     //open block table read                     blocktable blocktable = transaction.getobject(database.blocktableid, openmode.forread) blocktable;                      //open block table record model space write                     blocktablerecord blocktablerecord = (blocktablerecord)transaction.getobject(blocktable[blocktablerecord.modelspace], openmode.forwrite);                      dbobject newobject = drawer.drawobject(blocktablerecord);                      transaction.addnewlycreateddbobject(newobject, true);                      transaction.commit();                 }             }         }     } 

injecting func<>: seemed give me similar result, better readability.

[commandmethod("test", commandflags.session)]     public void test()     {         performactiononblocktable(addlinetodrawing);         performactiononblocktable(addcircletodrawing);     }      private void performactiononblocktable(func<blocktablerecord, dbobject> action)     {         using (documentlock lockeddocument = application.documentmanager.mdiactivedocument.lockdocument())         {             using (database database = application.documentmanager.mdiactivedocument.database)             {                 using (transaction transaction = database.transactionmanager.starttransaction())//start transaction                 {                     //open block table read                     blocktable blocktable = transaction.getobject(database.blocktableid, openmode.forread) blocktable;                      //open block table record model space write                     blocktablerecord blocktablerecord = (blocktablerecord)transaction.getobject(blocktable[blocktablerecord.modelspace], openmode.forwrite);                      dbobject newobject = action(blocktablerecord);                      transaction.addnewlycreateddbobject(newobject, true);                      transaction.commit();                 }             }         }     }      private dbobject addlinetodrawing(blocktablerecord blocktablerecord)     {         line line = new line(new point3d(0, 0, 0), new point3d(10, 10, 0));         blocktablerecord.appendentity(line);          return line;     }      private dbobject addcircletodrawing(blocktablerecord blocktablerecord)     {         circle circle = new circle(new point3d(0, 0, 0), new vector3d(0, 0, 0), 10);         blocktablerecord.appendentity(circle);          return circle;     } 

i can have not done di, i'm quite new this. of more experienced developers give me pro's/con's of 2 different approaches? there in last approach that's red flag? seems more readable second approach. maybe i'm not understanding injection... in advance input!

you simple refactoring instead of options provided:

[commandmethod("test", commandflags.session)]    public void test() {      addlinetodrawing();      addcircletodrawing();    }    private void addlinetodrawing() {      createobjectonblocktable(     new line(new point3d(0, 0, 0), new point3d(10, 10, 0)));    }     private void addcircletodrawing() {      createobjectonblocktable(     new circle(new point3d(0, 0, 0), new vector3d(0, 0, 0), 10));    }     private void createobjectonblocktable(dbobject dbobject) {    using (var lockeddocument = application.documentmanager.mdiactivedocument.lockdocument())    using (var database = application.documentmanager.mdiactivedocument.database)    using (var transaction = database.transactionmanager.starttransaction()) {     // open block table read      var blocktable = (blocktable)transaction.getobject(database.blocktableid, openmode.forread);       // open block table record model space write      var blocktablerecord = (blocktablerecord)transaction.getobject(blocktable[blocktablerecord.modelspace], openmode.forwrite);       blocktablerecord.appendentity(dbobject);      transaction.addnewlycreateddbobject(dbobject, true);      transaction.commit();    }  }  

i think more readable.

update: run special logic, idea of using delegates. i'd refactor code this:

private void createobjectonblocktable(dbobject dbobject) {   performactiononblocktable((transaction, blocktablerecord) => {     blocktablerecord.appendentity(dbobject);       transaction.addnewlycreateddbobject(dbobject, true);       }); }  private void performactiononblocktable(action<transaction, blocktablerecord> action) {     using (var lockeddocument = application.documentmanager.mdiactivedocument.lockdocument())     using (var database = application.documentmanager.mdiactivedocument.database)     using (var transaction = database.transactionmanager.starttransaction()) {      // open block table read       var blocktable = (blocktable)transaction.getobject(database.blocktableid, openmode.forread);        // open block table record model space write       var blocktablerecord = (blocktablerecord)transaction.getobject(blocktable[blocktablerecord.modelspace], openmode.forwrite);        // run specific logic     action(transaction, blocktablerecord);      transaction.commit();     }   }   

(the rest of code same)

performactiononblocktable can reused run arbitrary logic using transaction , block table record.


Comments

Popular posts from this blog

c++ - Convert big endian to little endian when reading from a binary file -

C#: Application without a window or taskbar item (background app) that can still use Console.WriteLine() -

unicode - Are email addresses allowed to contain non-alphanumeric characters? -