2012-03-18 66 views
2

我正在創建n層應用程序體系結構。不同的層不知道任何其他內部實現,層之間的通信通過IoC/DI輔助的非常狹窄的接口進行處理。如何將對象類型從業務層傳遞到數據層

現在我將業務對象(在業務層中定義)傳遞給數據層。業務層本身並不知道如何以及在何處保存數據(通常數據庫,但業務層不應該知道這一點)。通過實施IDataReader將業務對象傳遞到數據層(此方法還支持將來場景中批量加載數據)。數據層讀取IDataReader中的所有數據,並調用一些存儲過程將數據保存到數據庫(如果保存了一個對象,則IDataReader返回「一行」)。

實際的問題是在這裏:

因爲我傳遞的IDataReader以數據層和其類型斷開數據,什麼是在這種情況下,最好的辦法,以確定地方的數據?

示例如果我將實際的「用戶」類型的業務對象傳遞給數據層,那麼數據層應該將數據保存到表「用戶」中。在另外一些情況下,數據可能會保存到某個不同的結構中,而與業務層的類型無關。

在當前實現中,我將業務對象的類型信息傳遞到數據層和數據層,檢查此類型並確定將數據放置在何處。

數據層檢查傳入數據並確定其位置或數據層是否應顯示可以保存數據的「位置」列表(enum?)是否正確?

在此先感謝!

/澄清

選項,我在這裏看到的是: 1.數據層提供了其中的數據可以保存 2.數據層給出巡視參數(如該類型ARG「plces」名單)以及存儲數據的地點

第一種選擇懲罰;如果我嘗試將「產品」類型的商業對象存儲到通常由類型「用戶」使用的結構中,那麼該怎麼辦?

第二種選擇懲罰;我必須將類型「Namespace1.Namespace2.User」映射到將其數據保存到表「用戶」的特定例程。所以手工做一些映射爲每種類型的...

/澄清2:

現在我找回這樣的:

service.Retrieve(typeof(Catalog), null, catalogArgs, e => catalogConverter.Read(e)); 

所以我通過typeof運算(目錄)到數據層。 ..所以我有數據層的類型信息。

現在在數據層中,我需要選擇難以從數據庫中獲取數據的「適配器」。我可以編寫巨大的if/switch結構來選擇適配器......這令人沮喪。我也可以寫屬性,並使用它像這樣:

[TypeAdapterAttribute("Namespace1.Namespace2.Catalog, and assembly info...")] 
class CatalogAdapter { ... } 

然後,我有代碼,不會從給定類型映射屬性值...

...但它是一點點膨脹和問題,硬編碼類型的字符串...

任何建議...?

/澄清3

我有想法,該系統可以通過「可插拔的業務模塊」進行擴展。這些模塊包含基本業務邏輯所不知道的業務對象(以及某些邏輯),數據層也完全不瞭解「插入的程序集」中包含的這些業務對象。此外部業務模塊沒有提及基礎業務層或數據層。當此外部程序集的業務對象被保存(=發送到數據層)時,數據層默認將其保存爲EAV樣式(http://en.wikipedia.org/wiki/Entity%E2%80%93attribute%E2%80% 93value_model)數據結構自動。由於這種數據結構可能存在一些性能問題,因此數據層必須有辦法將特定業務對象類型保存在其自己的專用數據結構(通常是具有一對一映射的表)中。所以問題來了,如何實現這個「選擇決定」:)

這裏的想法是,我可以創建很多新的業務對象,我可以將它們全部保存到數據層,而不需要實際編碼任何東西到數據層!之後,如果需要,我可以爲選定的業務對象創建自己的專用數據結構。

+0

說明3描述了全新的先決條件並提出了一個全新的問題。您可以根據屬性的數量進行決定。幾個屬性 - > EAV,很多屬性 - >專用模型。您可以確定像這樣的屬性'PropertyInfo [] props = obj.GetType()。GetProperties();' – 2012-03-19 14:09:02

+0

那麼,C3仍然是大約相同的系統。我只是試圖澄清系統的目標。我想我可能會打開新的問題後,我一直在考慮這一點.... – Harza 2012-03-19 17:10:19

回答

1

我建議您使用ORM(Entitiy Framework,NHibernate)或micro-ORM(PetaPoco,Dapper)將您的對象映射到數據存儲。
如果您有具體問題,請仔細研究並拍攝。

更新:我想我剛剛得到你所問的。
您需要爲每種類型在數據層中定義一種新方法。 所以:

public User GetUserById(int id); 
public void SaveUser(User user); 
public Product GetProductById(int id); 
public void SaveProduct(Product product); 
+0

如果使用任何ORM,我仍然需要知道如何「選擇實體從orm用於數據存儲」... – Harza 2012-03-18 19:48:59

+0

由於任何實現都是ORM特定的,我不能給你一個通用的代碼示例。你想做什麼(將對象映射到表)是ORM的全部目的。我會說,看看PetaPoco,因爲它非常簡單。該文檔是一個完整的代碼示例頁面。 – David 2012-03-18 20:06:01

+0

@Harza:是的,但是您不認爲表格和專欄,而是關於您的業務對象及其屬性。看我上面的例子。 – 2012-03-18 20:06:51

1

如果你想創建一個從業務層斷開自己的數據庫層,你也可以介紹與合同

List<Customer> customers = DB.LoadCustomers(); 

數據層可以用通用的工作一個單獨的程序鍵入參數並通過Reflection獲取有關業務對象的信息。這提供了層的良好分離,因爲數據層不需要引用業務組件。

List<Customer> customers = DataContext.Query<Customer>.Load(); 

Customer customer = DataContext.Query<Customer>.Load(custID); 

O/R-映射器通常這樣工作

List<Customer> customers = Context.Query<Customer>() 
    .Where(cust => cust.Name.StartsWith("A")) 
    .OrderBy(cust => cust.Name) 
    .ToList(); 

在這些實施例中,數據層創建並填充業務對象。否則,業務層必須知道表列名稱。

(注意:這裏我沒有提到具體的數據接口。)


UPDATE:

如果你想創建一個從業務層diconnected自己的數據庫層也可以引入與合同

public interface ICustomer 
{ 
    string LastName { get; set; } 
    string FirstName { get; set; } 
    ... 
} 

兩個獨立的組件,該數據層和業務層將有這些合同的參考。

在數據層,你會類似於

public List<T> LoadAll<T>(Func<T> create) 
{ 
    var list = new List<T>(); 
    if (T is ICustomer) { 
     string sql = "SELECT * FROM tblCustomer"; 
     ... 
     while (reader.NextResult()) { 
      ICustomer cust = (ICustomer)create(); 
      cust.FirstName = reader.GetString("FirstName"); 
      ... 
      list.Add((T)cust); 
     } 
    } else if (T is IOrder) { 
     ... 
    } 
    return list; 
} 

在業務層的方法,你會寫

List<ICustomer> customers = DbLayer.LoadAll<ICustomer>(() => new Customer()); 

現在,你的數據層可以與客戶不知道你的客戶類並且沒有對業務層組件的引用。

+0

解決方案嘗試避免使用對象映射,數據通過使用IDataReader的層傳輸。在查詢案例中,數據層將IDataReader提供給業務層,可用於讀取數據並在需要時實現對象。使用IDataReader並不是問題,只是「如何告訴數據層類型來處理沒有實際類型」 – Harza 2012-03-18 19:59:58

+0

可能是這樣的:'IDataReader customers = DataLayer.LoadAll(「Customers」);'。但是,您的業務層必須知道列名稱。 – 2012-03-18 20:10:39

+0

在你的例子中,你通過字符串文字「Customers」告訴需要獲取什麼樣的數據,這是這個問題的關鍵點。現在我正在做類似的事情,但使用System.Type作爲參數。數據層然後以某種方式確定獲得「客戶」的方式。如果你需要命名空間,我只是嘗試在這裏解決最合適的解決方案(字符串,類型,別的東西).... – Harza 2012-03-18 20:24:21

相關問題