2013-11-27 47 views
0

某人能否提供一個結構/模式允許以下兩項工作:如何允許一次性資產的多餘嵌套'創作'?

public void DoSomething() 
{ 
    using (var connection = Connect()) 
    { 
     connection.DoThatThing(); 
    } 
} 
public void DoSomethingTwice() 
{ 
    using (var connection = Connect()) 
    { 
     DoSomething(); 
     DoSomething(); 
    } 
} 

我心目中的是,當DoSomethingTwice()被調用時,只有一個連接應建立,並應該得到重新利用通過DoSomething調用(但不是由他們處置!)。

編輯:我打算使用這種模式很多,所以我想避免重載的DoSomething(連接),並將複雜性隱藏在Connect()方法中。

我的最大努力將作爲答案。

回答

0

除非DoSomething處置它們,你正在做的事情應該達到這一點。

+0

'DoSomethingTwice'調用'DoSomething'兩次,從而創建兩個連接,當只需要一個時。如果重構,它可以重新使用連接。 – Servy

0

我會通過connection作爲參數。

public void DoSomething(Connection connection) 
{ 
    connection.DoThatThing(); 
} 
public void DoSomethingTwice() 
{ 
    using (var connection = Connect()) 
    { 
     DoSomething(connection); 
     DoSomething(connection); 
    } 
} 
+0

這不像OP的代碼,它刪除了一次只執行一次的公共方法,也允許外部代碼注入自己的連接。 – Servy

0

這聽起來像你想通過你的連接到DoSomething方法,像這樣:

public void DoSomething(Connect connection) 
{ 
    connection.DoThatThing(); 
} 

public void DoSomethingTwice() 
{ 
    using (var connection = new Connect()) 
    { 
     DoSomething(connection); 
     DoSomething(connection); 
    } 
} 
3

具有接受連接的私有方法,然後是創建連接並通話公共方法出任意數量的私有方法:

public void DoSomething() 
{ 
    using (var connection = Connect()) 
    { 
     DoSomething(connection); 
    } 
} 

public void DoSomethingTwice() 
{ 
    using (var connection = Connect()) 
    { 
     DoSomething(connection); 
     DoSomething(connection); 
    } 
} 

private void DoSomething(Connection connection) 
{ 
    connection.DoThatThing(); 
} 
2

您應該using內的動作隔離到它自己的方法,

public void DoSomething() 
{ 
    using (var connection = Connect()) 
    { 
     DoSomething(connection); 
    } 
} 

public void DoSomethingTwice() 
{ 
    using (var connection = Connect()) 
    { 
     DoSomething(connection); 
     DoSomething(connection); 
    } 
} 

private void DoSomething(IDbConnection connection) 
{ 
    connection.DoThatThing(); 
} 

也許,隔離using部分以及,

public void DoSomething() 
{ 
    UsingConnection(connection => DoSomething(connection)); 
} 

public void DoSomethingTwice() 
{ 
    UsingConnection(
     connection => 
     { 
      DoSomething(connection); 
      DoSomething(connection); 
     }); 
} 

private void DoSomething(IDbConnection connection) 
{ 
    connection.DoThatThing(); 
} 

private void UsingConnection(Action<IDbConnection> action) 
{ 
    using (var connection = Connect()) 
    { 
     action(connection); 
    } 
} 
+0

哦來吧:> UsingConnection是如此不必要。 – kaptan

+1

實際上,我承認也許在這種情況下......但是當你需要做很多預處理和後處理時,它可能會變得非常有用。你添加一個'try',2'catch'和'finally',它就變成了*必須*。 – rae1

+0

只暴露'UsingConnection'方法將使得客戶端無法做一些事情,如果它管理連接的生命週期,這將是可能的,但另一方面保證實現客戶端代碼不會做它所做的事情不允許。當與包含「保存上下文」和「恢復上下文」方法的驅動程序接口時,這可能很重要,但要求它們按LIFO順序使用(如果一個上下文是「打開」的,可以打開一秒鐘,使用它,關閉它,然後恢復第一個工作,但第二個是開放的... – supercat

0

這裏有一個連接:

public Connection : IDisposable 
{ 
    public ExpensiveNativeConnection _nativeConnection; 
    public void DoThatThing() 
    { 
     _nativeConnection.Foo(); 
    } 
    public void Dispose() 
    { 
     _nativeConnection.Dispose; 
     _nativeConnection = null; 
    } 
} 
public UnDisposableConnectionCopy : Connection 
{ 

    public override void Dispose(){} // does nothing; 

} 

這裏是連接():

public Connection Connect() 
{ 
    if (this._connection == null) 
    { 
     this._connection == new Connection(); 
     return this._connection; 
    } 
    else 
    { 
     //References _connection's ExpensiveNativeConnection but can't dispose it. 
     return _connection.MakeUnDisposableConnectionCopy(); 
    } 
} 

這是否感?