2016-09-30 98 views
0

我的經驗讓我更習慣於我的程序中的以下結構。假設這是一個.NET WPF應用程序。您創建一個WPF項目,一個業務邏輯項目(類庫),一個數據訪問項目(類庫)和一個實體項目(類庫)。 WPF項目通過業務邏輯層到達數據訪問層。這些實體是輕量級的DTO,可以自由流動。LINQ to SQL和N層分層

我的問題是這樣的。我喜歡LINQ to SQL實體,除非我用它來創建我的實體,我不僅用實體關係的直接表格,還將我的實體放在我的數據訪問項目中,並強制我的UI項目對我的數據訪問項目。誠然,我可以讓我的DataContext內部(我認爲它應該是默認情況下),除了我的DTO仍然在我的數據訪問項目,它仍然強迫我的UI項目有一個對我的數據訪問項目的引用。

我在這裏丟失了什麼東西,或者有另一種方法來用LINQ to SQL來解析我的DTO,或者我應該關心它嗎?

+1

你很傷心你的DTO是分開的項目「實體項目」。所以你的UI只需要參考實體項目。然後,DataAccess和UI項目都將參考實體項目,而不需要了解彼此 – Fabio

+0

我對我的UI項目和我的數據訪問項目並不感到難過,因爲它們不需要知道對方如何工作。我相信這是一件好事。我的UI項目不需要更改,即使在數據庫切換到MySQL或DB2(而不是SQL Server)的情況下也不需要更改。爲什麼我必須爲此向客戶發佈新版UI?當然,每個人都必須參考DTO。 –

+0

那麼你的問題是什麼? 'UI'抽象了所需的行爲和數據。 Businees邏輯將實現UI的抽象,並抽象出所需的數據服務。 「數據訪問」將實現「業務邏輯」的服務抽象。 'DTO project'實現'UI'的數據模型抽象,如果可能的話''數據訪問'用作實體,或者你在'數據訪問'的實體和數據模型抽象之間建立映射。通過這種方式,您的依賴流將從高層到細節層,其中細節層可以更容易地更改 – Fabio

回答

0

如果我們遵循依賴倒置原則

  • 高層模塊不應該依賴於低級別的模塊。兩者都應該取決於抽象。
  • 抽象不應該依賴細節。細節應該取決於抽象。

所以你的情況UIBusiness logic不應該取決於Data access。抽象的實體不應該依賴的LINQ to SQL

然後細節,我們開始設計我們從高位層的應用

1創建實體的抽象項目

public interface ICustomer 
{ 
    int Id { get; set; } 
} 

2創建項目的業務邏輯抽象用於UI項目

public interface ICustomerService 
{ 
    List<ICustomer> LoadTop50(); 
} 

3創建UI項目

3.1創建它們使用ICustomerICustomerService用於顯示人的信息

通知UI邏輯:UI只依賴於抽象,沒有其它層次的知識。

4創建商業項目

4.1獲取數據

namespace Business.DataAccessAbstractions 
    { 
     public interface ICustomerDataAccess 
     { 
      List<ICustomer> Load(int topAmount); 
     } 
    } 

4創建DataAccess抽象。2實施ICustomerService其使用ICustomerDataAccess

public class CustomerService : ICustomerService 
{ 
    private DataAccessAbstractions.ICustomerDataAccess _dataAccess; 

    public CustomerService(DataAccessAbstractions.ICustomerDataAccess dataAccess) 
    { 
     _dataAccess = dataAccess; 
    } 

    public IEnumerable<ICustomer> LoadTop50() 
    { 
     const int TOP_NUMBER = 50; 
     return _dataAccess.Load(TOP_NUMBER); 
    } 
} 

通知抽象:Business項目創建數據訪問抽象。並實現抽象,UI將用於顯示數據。

5創建數據訪問項目

5.1 LINQ to SQL創建實體。

5.2執行Business.DataAccessAbstractions.ICustomerDataAccess接口。

5.2.1製作實體,由LINQ to SQL產生,實現ICustomer

[Table(Name="dbo.Customer")] 
    public partial class Customer : INotifyPropertyChanging, 
            INotifyPropertyChanged, 
            ICustomer 
    { 
     private int _Id; 

     [Column(Storage="_Id", 
       AutoSync=AutoSync.OnInsert, 
       DbType="Int NOT NULL IDENTITY", 
       IsPrimaryKey=true, 
       IsDbGenerated=true)] 
     public int Id 
     { 
      get 
      { 
       return this._Id; 
      } 
      set 
      { 
       if ((this._Id != value)) 
       { 
        this.OnIDChanging(value); 
        this.SendPropertyChanging(); 
        this._Id = value; 
        this.SendPropertyChanged("Id"); 
        this.OnIDChanged(); 
       } 
      } 
     } 
    } 

你只需要添加ICustomer來實現的接口列表。或者創建/生成一些「映射邏輯」,將由LINQ to SQL生成的實體轉換爲將推動ICustomer的實例。我發現添加ICustomer是這個示例最簡單的方法。

注:DataAccess項目只對抽象的依賴是通過使用LINQ to SQL

6創建主要項目這將加劇所有依賴在一起,並啓動你的用戶界面來實現。

注意:此項目將具有您的應用程序正常工作所需的所有參考。

摘要

通過這種方法,你用戶界面將不會依賴於LINQ to SQL細節。

使用這種方法,您可以自由修改DataAccess的實現,直到修改不會破壞高層次的抽象。

當然,如果您決定爲客戶添加您想在UI中使用的新數據字段,那麼您需要修改整個依賴關係鏈。