JSp*_*ang 2 c# dependency-injection coding-style autocad
我有一个项目,可以添加元素到AutoCad绘图.我注意到我开始在多种方法中编写相同的十行代码(为简单起见仅显示两行).
初步实施: 您会注意到唯一真正改变的是添加一个Line而不是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 the transaction
{
//Open the block table for read
BlockTable blockTable = transaction.GetObject(database.BlockTableId, OpenMode.ForRead) as BlockTable;
//Open the block table record model space for 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 the transaction
{
//Open the block table for read
BlockTable blockTable = transaction.GetObject(database.BlockTableId, OpenMode.ForRead) as BlockTable;
//Open the block table record model space for 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();
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
注入:这接近删除了代码的重复,但我认为可读性差.
[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 the transaction
{
//Open the block table for read
BlockTable blockTable = transaction.GetObject(database.BlockTableId, OpenMode.ForRead) as BlockTable;
//Open the block table record model space for write
BlockTableRecord blockTableRecord = (BlockTableRecord)transaction.GetObject(blockTable[BlockTableRecord.ModelSpace], OpenMode.ForWrite);
DBObject newObject = drawer.DrawObject(blockTableRecord);
transaction.AddNewlyCreatedDBObject(newObject, true);
transaction.Commit();
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
注入Func <>:这似乎给了我类似的结果,具有更好的可读性.
[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 the transaction
{
//Open the block table for read
BlockTable blockTable = transaction.GetObject(database.BlockTableId, OpenMode.ForRead) as BlockTable;
//Open the block table record model space for 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;
}
Run Code Online (Sandbox Code Playgroud)
我可以诚实地说,我对DI没有做太多,所以我对此很新.你们中任何一位经验丰富的开发人员可以给我两种不同方法的Pro/Con吗?最后一种方法中有什么东西是红旗吗?它似乎比第二种方法更具可读性.也许我甚至都不完全理解注射...在此先感谢您的投入!
您可以执行简单的重构,而不是您提供的选项:
[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 the block table for read
var blockTable = (BlockTable)transaction.GetObject(database.BlockTableId, OpenMode.ForRead);
// Open the block table record model space for write
var blockTableRecord = (BlockTableRecord)transaction.GetObject(blockTable[BlockTableRecord.ModelSpace], OpenMode.ForWrite);
blockTableRecord.AppendEntity(dbObject);
transaction.AddNewlyCreatedDBObject(dbObject, true);
transaction.Commit();
}
}
Run Code Online (Sandbox Code Playgroud)
我认为这更具可读性.
更新:要运行特殊逻辑,我喜欢使用委托的想法.我会像这样重构代码:
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 the block table for read
var blockTable = (BlockTable)transaction.GetObject(database.BlockTableId, OpenMode.ForRead);
// Open the block table record model space for write
var blockTableRecord = (BlockTableRecord)transaction.GetObject(blockTable[BlockTableRecord.ModelSpace], OpenMode.ForWrite);
// Run specific logic
action(transaction, blockTableRecord);
transaction.Commit();
}
}
Run Code Online (Sandbox Code Playgroud)
(其余代码将是相同的)
PerformActionOnBlockTable 可以重复使用事务和块表记录来运行任意逻辑.
| 归档时间: |
|
| 查看次数: |
737 次 |
| 最近记录: |