2013-03-11 66 views
0

我有一個隱藏不同ADO.NET提供者的差異,並有大量的代碼就像一個dll:如何動態地處理對dll的依賴關係?

private static void AppendProviderSpecificParameterCmdStr(StringBuilder sb, DbCommand cmd, string fieldNameToUse, ComparisonOperator oprtr, string parameterName) 
{ 
    if (cmd is System.Data.OracleClient.OracleCommand || cmd is Oracle.DataAccess.Client.OracleCommand) 
    { 
     sb.AppendFormat("{0}{1}:{2}", fieldNameToUse, GetComparisonOperatorStr(oprtr, cmd), parameterName); 
    } 
    else if (cmd is SqlCommand) 
    { 
     sb.AppendFormat("{0}{1}@{2}", fieldNameToUse, GetComparisonOperatorStr(oprtr, cmd), parameterName); 
    } 
    else if (cmd is OleDbCommand) 
    { 
     sb.AppendFormat("{0}{1}?", fieldNameToUse, GetComparisonOperatorStr(oprtr, cmd)); 
    } 
    else 
    { 
     throw new Exception(string.Format("Wrong database command type: {0},", cmd.GetType())); 
    } 
} 

其中比較運營商是我自己的枚舉。

Oracle.DataAccess存在於所有具有oracle客戶機的機器上,並且此代碼對我的需求已滿足。但是現在我遇到了只有SqlClient的情況,他們根本就不需要oracle。所以我的代碼只有在我複製Oracle.DataAccess.dll時纔有效,這自然是一個可怕的解決方案。這應該如何以正確的方式完成?

謝謝-matti

回答

1

我不會調用依賴於dll一個可怕的解決方案。您的解決方案支持Oracle,因此您的解決方案中有一個Oracle dll - 它就是這樣。

也就是說,有些事情可以抽象出命令類型。

One - 創建實現接口的完整數據訪問方法。我將其分類爲更多通用數據訪問的幫助程序或實用程序方法。您可以改爲將具體接口聲明爲域名,例如客戶 - 例如ICustomerDA。在你的情況下,你會有3個ICustomerDA.Insert的實現,並將數據庫細節埋在裏面。你的主要代碼只需要瞭解ICustomerDA。這可能是我在更大的解決方案中所要做的,因爲RDBMS之間的差異和功能遠遠超出了參數聲明。

二 - 如果你想堅持更多的幫助/實用的想法,你可以創建一個接口,爲數據庫對象的包裝,說IDBCommand。 IDbCommand的會躲在底層的命令對象,然後實現有.AppendProviderSpecificParameterCmdStr方法,這樣可以讓你做什麼樣的具體實現:

OracleDbHelper : IDbCommand... 
    public void AppendProviderSpecificParameterCmdStr(...){ 
    sb.AppendFormat("{0}{1}:{2}", fieldNameToUse, GetComparisonOperatorStr(oprtr, cmd), parameterName); 
    } 

IDBCommand cmd = DAFactory.GetCommand(); 
cmd.AppendProviderSpecificParameterCmdStr(... 

到這兩種解決方案的核心是由一個共同的接口引用您的主要項目而不是單個類型。一旦你這樣做了,你可以在你的工廠中使用反射,或者更好,類似MEF來創建實際類型。

+0

感謝您的回答。我必須在稍後檢查。我稱它爲可怕的,因爲將Oracle.DataAccess.dll複製到沒有oracle的客戶對我而言並不好。它也可能涉及一些法律問題? – 2013-03-13 07:05:15

+0

我完全理解你的意思。但是,我也發現,近些年來,語義或「最佳實踐」被放在編譯和運行沒有問題的代碼之前。您可能會對授權有所瞭解,但我懷疑這是一個問題:「在大多數情況下,Oracle不會收取任何費用來分發Oracle客戶端,也不會收取第三方應用程序的ODP.NET費用。但是,最好諮詢許可協議,您從中獲得Oracle軟件的權利....「http://www.oracle.com/technetwork/database/windows/faq-093106.html#distribute – 2013-03-14 13:46:35

+0

謝謝!我忘了這個答案,但這實際上有點像我上週做的事情(包裝)。也許下意識:)我的解決方案是這樣的,我把這個問題:http://stackoverflow.com/questions/21988358/what-does-a-using-statement-without-variable-do-when-disposing – 2014-02-25 09:10:49

0

所以我的代碼只能如果我複製Oracle.DataAccess.dll

除非你有本地OCI的DLL,例如,因爲你已經安裝了Oracle客戶端。

爲避免強制用戶安裝完整的Oracle客戶端,您可以將Oracle客戶端的DLL與應用程序一起分發。如果用戶從不選擇連接到Oracle,這些DLL永遠不會被調用,只是靜靜地坐在那裏,不會造成任何麻煩。

有關如何分配內容以及如何涵蓋32位和64位的一些提示,請參閱this post

我們有一個本土的抽象層,目前與Oracle和MS SQL Server一起工作(並且可以移植到任何帶有體面的ADO.NET提供者的DBMS),而且這個系統迄今爲止工作得非常好。

+0

沒有。我不需要安裝其他dll。這是嘗試和證明。只有Oracle.DataAccess.dll在沒有任何類型的oracle客戶端的機器上工作正常。 – 2014-02-12 12:24:50

+1

@matti Oracle.DataAccess.dll是舊的「混合模式」ODP.NET,它需要本機DLL。也許你的意思是Oracle.ManagedDataAccess.dll(新的「完全託管」ODP.NET)? – 2014-02-12 13:53:01

+0

對於遲到的回答感到抱歉。這沒有原生的DLL工作。只複製Oracle.DataAccess.dll。請注意,它並未在SQL Server環境中使用它。我無法解釋這一點或知道任何關於。這個託管的DLL對我來說是全新的。我得看看這個。謝謝。 – 2014-02-25 09:07:54