這聽起來像是一個變異的頗具異國情調的未來生活方式描述的第272頁my book。我認爲你應該可以用Decorator來解決這個問題,而不是發明一個新的界面。
首先,讓我們想象一下所涉及的類型是什麼樣子。這聽起來像你有一些存儲庫接口。讓我們把一個代表庫IFooRepository
:
public interface IFooRepository
{
Foo Read(int id);
}
它還聽起來像是你有跟數據庫的具體實現。良好的措施,讓我們給具體的類Inspection Properties,這樣我們就可以查詢庫對象要問它的連接字符串,它使用了:
public class SqlFooRepository : IFooRepository
{
private const string connectionString;
public SqlFooRepository(string connectionString)
{
if (connectionString == null)
throw new ArgumentNullException("connectionString");
this.connectionString = connectionString;
}
public string ConnectionString
{
get { return this.connectionString; }
}
public Foo Read(int id)
{
// SQL query code goes here...
}
}
這使您可以創建一個裝飾(或者它是一個Decoraptor):
public class ConnectionstringAwareFooRepository : IFooRepository
{
private SqlFooRepository repo;
public Foo Read(int id)
{
var connectionstring =
ConfigurationManager.ConnectionStrings["foo"].ConnectionString;
if (this.repo == null ||
this.repo.ConnectionString != connectionString)
this.repo = new SqlFooRepository(connectionString);
return this.repo.Read(id);
}
}
這種設計的好處是,它完全從屏蔽處理髮現新的連接字符串的管理方面的客戶端代碼。所有客戶看到的是IFooRepository
。
但請注意,上述示例不是線程安全的。如果您需要在多線程環境中使用此解決方案,則需要使其成爲線程安全的。
由於ConnectionstringAwareFooRepository
類從配置文件中讀取,我強烈建議您將它與您的代碼庫中的Composition Root放在同一部分。
在詢問用戶輸入之前創建這些對象是否有意義?是否有一個默認的連接字符串直到用戶更改設置才使用? –
是的,默認情況下程序是使用默認連接字符串安裝的。然後,如果用戶更改了連接,那麼該數據庫名稱和服務器將在下次啓動該程序時成爲新的默認值。幾乎所有的程序都需要數據庫訪問,所以它需要從一開始就創建這些對象。 –
*「下一次啓動程序」*你不能只是將新的連接字符串保存在配置文件中,然後繼續? –