[英]Dynamic swappable Data Access Layer
我正在編寫一個數據驅動的WPF客戶端。 客戶端通常從WCF服務中提取數據,該服務查詢SQL數據庫,但我希望選擇直接從SQL或其他任意數據源提取數據。
我想出了這個設計,並想聽聽你對它是否是最好的設計的看法。
首先,我們要從SQL中提取一些數據對象。
// The Data Object with a single property
public class Customer
{
private string m_Name = string.Empty;
public string Name
{
get { return m_Name; }
set { m_Name = value;}
}
}
然后我計划使用所有數據訪問層應該實現的接口。 假設一個人也可以使用抽象類。 思考?
// The interface with a single method
interface ICustomerFacade
{
List<Customer> GetAll();
}
可以創建SQL實現。
// Sql Implementation
public class SqlCustomrFacade : ICustomerFacade
{
public List<Customer> GetAll()
{
// Query SQL db and return something useful
// ...
return new List<Customer>();
}
}
我們還可以創建一個WCF實現。 WCF的問題在於它不使用相同的數據對象。 它創建了自己的本地版本,因此我們必須以某種方式復制細節。 我想可以使用反射來復制相似字段的值。 思考?
// Wcf Implementation
public class WcfCustomrFacade : ICustomerFacade
{
public List<Customer> GetAll()
{
// Get date from the Wcf Service (not defined here)
List<WcfService.Customer> wcfCustomers = wcfService.GetAllCustomers();
// The list we're going to return
List<Customer> customers = new List<Customer>();
// This is horrible
foreach(WcfService.Customer wcfCustomer in wcfCustomers)
{
Customer customer = new Customer();
customer.Name = wcfCustomer.Name;
customers.Add(customer);
}
return customers;
}
}
我還計划使用工廠來決定使用哪個立面。
// Factory pattern
public class FacadeFactory()
{
public static ICustomerFacade CreateCustomerFacade()
{
// Determine the facade to use
if (ConfigurationManager.AppSettings["DAL"] == "Sql")
return new SqlCustomrFacade();
else
return new WcfCustomrFacade();
}
}
這就是通常使用DAL的方式。
// Test application
public class MyApp
{
public static void Main()
{
ICustomerFacade cf = FacadeFactory.CreateCustomerFacade();
cf.GetAll();
}
}
我感謝你的想法和時間。
您可以通過非常靈活的軟件方法開始。 您已經遇到了主要問題:數據提供者合同( ICustomerFacade
)必須指定所有實施者使用的數據對象。 SQL和WCF數據提供程序都必須返回相同的數據對象。
那部分你標記為“這太可怕了”? 實際上並不是那么糟糕。 你正在迭代兩次,是的,但是你這樣做是為了提供更強大,更靈活的軟件架構。 性能不會那么糟糕(除非你在列表中迭代很多項),你的系統將能夠在調用Web服務和直接調用SQL服務器之間切換(一般來說這是不是一個好主意)隨意。
消除雙重迭代可以做的一件事是讓數據合同依賴於數據對象的抽象。 例如,他們會返回ICustomer
而不是Customer
。 然后,只要他們實現了ICustomer
等接口,您的SQL Server對象和WCF數據對象就可以完全不同。
其他建議:
IList
(甚至IEnumerable
)而不是List
。 有兩種方法可以解決WCF實現中的數據對象與數據存儲區返回的數據對象之間的差異:
在創建WCF代理時,請確保重用引用程序集中的所有類型 (如果使用VS選項而不是直接調用svcutil,則在“高級”對話框中)。
在DTO(數據對象)上有一個Clone()或CopyFrom()類型方法,以便您可以將對象從本地生成的命名空間映射到常規項目命名空間,然后再返回
我會實現選項1 - 選項2肯定會工作,但這是一個非常緩慢的方法。 有時當你告訴VS在生成代理時重用引用的類型時,它仍然會生成DTO的本地定義 - 在這種情況下,你可以直接進入生成的Reference.cs
類文件並刪除所有定義,並繼續使用常規項目命名空間中定義的版本。
除了WCF問題,您似乎走在了正確的軌道上。
我個人認為如果你在談論.NET到.NET,svcutil.exe是一個反模式。 這是一個沒有實際價值的額外突破點。 如果您正在與外部服務或不同平台集成,則svcutil.exe是一個不錯的選擇。
通常,對於每個服務,應該有一個額外的Contracts程序集,其中包含服務的所有服務接口和datacontracts。 該程序集由服務和客戶端引用。 這樣,當進行更改時,它們將反映在客戶端和服務器中。
http://blog.walteralmeida.com/2010/08/wcf-tips-and-tricks-share-types-between-server-and-client.html
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.