2013-05-14 57 views
0

我有困難時期試圖解決一個解決方案中的項目之間的交叉依賴。 該解決方案是一個具有多個項目的asp.net應用程序。如何解決交叉依賴

Web項目使用SLN.Core項目中的sessionwrapper類的服務。 聲明如下:

public sealed class SW 
{ 
    public static tblUserRow User 
    { 
     get 
     { 
      if (HttpContext.Current == null) return null; 
      return HttpContext.Current.Session["dtUser"] == null ? null : (tblUsersRow)(HttpContext.Current.Session["dtUser"] as tblUsers).Rows[0]; 
     } 
    } 

    public static void User_Load(string userId) 
    { 
     tblUsers users = new tblUsers(); 
     users.LoadByID(userId); 
     if (users.Count != 0) 
     { 
      HttpContext.Current.Session["dtUser"] = users; 
     } 
    } 
} 

的tblUserRow是在一個單獨的項目模型的用戶類(強類型DataTable)的模型定義的一部分。 SW類中還有其他一些方法,但不相關。 因此,在SLN.Web中,我可以訪問像「SW.User.Name」這樣的用戶數據。

模型項目由結構(模型類)和兩個不同名稱空間中的數據庫引擎類組成。

如上所示,SW類依賴於聲明User的模型。 到此爲止,一切正常。

但事實是,模型對象,需要用戶,公司等數據時,首次創建類,使他們可以得到默認值。 F.Ex:如果您創建了新的發票,可以很方便地獲取用戶(客戶)分配的倉庫或付款類型。

而且根據工作要求,數據庫引擎需要公司或用戶數據來獲取數據庫(每個公司一個)或保存包含用戶信息的日誌條目。

直到那些對象在每次調用數據庫引擎類或甚至方法時傳遞的那一天,但現在我重構了這一點,我認爲如果可以直接在各自的對象上獲取該信息,它會更乾淨, SW的地方。

但它們之間存在交叉依賴性。而且由於SW成員被聲明爲靜態的,所以他們可以堅持獨立於會話,我無法創建一個接口。

有什麼建議嗎?

更新:以前解決的用戶數據的範圍有問題,所以我在這裏糾正了。 另外我會添加一些更好的理解代碼。從這裏VB,對不起帥哥,但這是一個很好的多樣性模式。在SLN.Models的tblUser模型

例子:

<DesignerCategory("Code"), System.SerializableAttribute()> 
Partial Public Class tblUsers 
    Inherits TypedTableBase(Of tblUsersRow) 

    <DebuggerNonUserCodeAttribute()> 
    Public Sub New() 
     MyBase.New() 
     BeginInit() 
     InitClass() 
     EndInit() 
    End Sub 

    <DebuggerNonUserCodeAttribute()> 
    Private Sub InitClass() 
     TableName = TABLE_NAME 

     With Columns 
      .Add(New DataColumn(FIELD_ID, GetType(String))) 
      .Add(New DataColumn(FIELD_Name, GetType(String))) 
      ... 
      'Added that last columns as example 
      .Add(New DataColumn(FIELD_Company, GetType(String)) With {.DefaultValue=SW.Company.ID}) 
      .Add(New DataColumn(FIELD_Warehouse, GetType(String)) With {.DefaultValue=SW.Company.Warehouse}) 
     End With 

     Dim keys(1) As DataColumn 
     keys(0) = Columns(0) 
     PrimaryKey = keys 
    End Sub 
... 

    <DebuggerNonUserCodeAttribute()> 
    Public Sub LoadByID(Id As String) 
     Rows.Clear() 
     Merge(New SLN.DBEngine.Generic(SW.Company.Connection, doLog:=False).ExecuteQuery(COMMAND_LOADBY_ID, Id)) 
    End Sub 
... 
End Class 
Partial Public Class tblUsersRow 
    Inherits DataRow 
    <DebuggerNonUserCodeAttribute()> 
    Friend Sub New(ByVal builder As DataRowBuilder) 
     MyBase.New(builder) 
    End Sub 

    <DebuggerNonUserCodeAttribute()> 
    Public Property ID() As String 
     Get 
      Return DirectCast(MyBase.Item(0), String) 
     End Get 
     Set(value As String) 
      MyBase.Item(0) = value 
     End Set 
    End Property 

    <DebuggerNonUserCodeAttribute()> 
    Public Property Name() As String 
     Get 
      Return DirectCast(MyBase.Item(1), String) 
     End Get 
     Set(value As String) 
      MyBase.Item(1) = value 
     End Set 
    End Property 
    ... 
End Class 

**模型類都是這樣,而我得到了多個數據庫上的EF的解決方案。他們在哪裏明白datatables。

是的,還有另一個名爲Company的模型類,也用於SW中提供會話中的公司數據(多個用戶,多個公司登錄到) 您可以看到,在用戶構建時,可以從SW中檢索默認值。每個例子的發票頭等其他模型也一樣。這是我想要的行爲。到目前爲止,所有獲得默認值的模型,他們都會得到一個完整的對象作爲New()的參數。某些模型只需要來自+25場地對象的一個​​場地。 他們還使用DBEngine來加載/查詢/保存/刪除數據。

在SLN中。網絡可能會看到類似這樣的(登錄):

SW.Company_Load(ddlCompany.Text) 
sDescription = New Generic(SW.Company.Connection,False).ExecuteQuery("sp_Warehouse_LoadBy_Id",SW.User.Warehouse).Rows(0)("rDescription").ToString 

Thaaats a roough example。

所以SLN.Core.SW需要SLN.Models.tblUsersRow和SLN.DBEngine.Generic

而且SLN.Models.tblUsers需要SLN.DBEngine也希望得到SLN.Core.SW .. 。

SLN.DBEngine ......需要SLN.Core.SW所以他知道的DB指向(一些其他的東西)

而且SLN.Web需要所有的人。 (嘆氣!)

清除? (Errr ...)

+0

如果_currentUser是靜態的,它將在所有線程/請求之間共享,並且在整個系統中將只有一個當前用戶。這就是你真正想要做的事情嗎? – 2013-05-14 10:32:37

+0

是的,那是對象的測試/初始版本。它被更正爲專門使用會話。謝謝。 – Sergio 2013-05-14 14:30:58

回答

0

我終於通過移動與那些SW類相同的核心項目中的數據實體類解決了交叉dependecy。 也將DB訪問引擎類移至CORE,因此在模型項目中只有實體,並且可以依靠CORE訪問數據庫。 CORE項目不依賴於任何東西,因爲它的所有實體都在其上,並且還具有數據庫訪問引擎。

最後,這是另一個壞結構設計的問題。

我也想讚揚Fendy,因爲在其他情況下答案很好。 @恩迪,如果你知道給你信用的方式,請告訴我。 謝謝。

+0

Upvote就夠了。如果我的回答沒有具體回答你的問題,upvote就足夠了。並請在我的答案評論解釋,以便其他用戶不會覺得混亂。 – Fendy 2013-06-07 03:02:11

1

很難理解你的故事。但是從我得到的結果來看,你的模型需要current_user來創建對象(當然,我沒有得到爲什麼需要的業務邏輯),並且你的web sln需要current_user的模型。

基本上,流動應該是這樣的:

  • 用戶類被定義
  • CURRENT_USER使用CURRENT_USER發起
  • ,該模型將啓動其它目的

有許多方式可以完成這一點,但我建議2解決方案:

  1. 這個實現是假定你做依賴注入來完成的。清潔,可測試。該設計適用於Model解決方案。

    public interface IUserProvider 
    { 
        User CurrentUser { get; } 
    } 
    
    public class ModelCreator 
    { 
        public ModelCreator(IUserProvider provider) 
        { 
         this.provider = provider; 
        } 
        IUserProvider provider; 
    
        public Invoice Get(){ 
         User currentUser = provider.CurrentUser; 
         // do other 
        } 
    } 
    
  2. 這個實現是不依賴注入來完成。不乾淨,但可嘲笑和易於設計。此設計適用於模型或實體解決方案。

    public static class UserProvider 
    { 
        private static Func<User> currentUserDelegate = new Func<User>(NullUser); 
        public static Func<User> CurrentUserDelegate 
        { 
         set 
         { 
          currentUserDelegate = value; 
         } 
        } 
    
        private static User NullUser() 
        { 
         return null; 
        } 
        public static User CurrentUser 
        { 
         get 
         { 
          return currentUserDelegate(); 
         } 
        } 
    } 
    

    用法:

    public sealed class SW 
    { 
        private static User _currentUser; 
        public static User GetCurrentUser() 
        { 
         if (_currentUser == null) 
         { 
          tblUsers users = new tblUsers(); 
          users.LoadByID(userId); 
          HttpContext.Current.Session["dtUser"] = users; 
          _currentUser = users[0]; 
         } 
         return _currentUser; 
        } 
    
        public static void User_Load(string userId) 
        { 
         UserProvider.CurrentUserDelegate = new Func<User>(GetCurrentUser); 
        } 
    } 
    
+0

感謝您的貢獻。我很抱歉,我不是更清楚。當我研究你的例子時,我必須說接口不允許用於靜態類或方法。 (這是問題)我可以使用更高版本更正代碼,以便可以看到最新的聲明。 – Sergio 2013-05-14 14:36:16

+0

如果您可以提供基於代碼的通用結構而不是故事中所描述的那樣,那將會更好。比如你聲明'這些是Model中的類,並且這些都在UI中' – Fendy 2013-05-14 14:39:40

+0

對此回答滿意,因爲在嘗試這種方法並發現它完全有效之後,我意識到這並不適用於我的場景。但是如果我的問題提出的話,重組不可能的時候,這將是一個很好的解決方案。 – Sergio 2013-06-07 07:44:29