2009-06-11 27 views
1

我最近有幾次在相對較小的時間範圍內多次訪問特定的類。VB.Net使用System.Reflection和System.Type初始化一個類來創建一個基於會話的單例擴展方法

因此,我一直在Session中存儲類的值,並試圖在頁面加載時訪問它,如果它不可用創建一個新實例並將其存儲在會話中。

因此,我試圖創建一個擴展方法來爲我做這個,而不是不斷地複製相同的代碼在不同的頁面上的不同的類。

我想使用這樣的

Dim objName as MyClass 

objName.SessionSingleton() 

到目前爲止,這是我爲我的擴展方法:

<Extension()> _ 
    Public Sub SessionSingleton(ByRef ClassObject As Object) 
     Dim objType As Type = ClassObject.GetType 
     Dim sessionName As String = objType.FullName 
     If TypeOf HttpContext.Current.Session(sessionName) Is objType And HttpContext.Current.Session(sessionName) <> "" Then 
      ClassObject = HttpContext.Current.Session(sessionName) 
     Else 
      Dim singleton As Object = New objType??????? 

      HttpContext.Current.Session(sessionName) = singleton 
      ClassObject = singleton 

     End If 
    End Sub 

我卡上時,我讓我的新做什麼我的班級的實例(它必須有一個新的()子)

我不知道該從哪裏去......或者即使這是最好的辦法。

+0

我認爲你需要你的類的對象工廠。 – RBarryYoung 2009-06-12 01:04:49

+0

我認爲這可能是正確的軌道...這是一個新概念,所以我正在做一些研究。如果我正確理解類/對象工廠,我仍然需要提前知道類是什麼,並且沒有辦法根據其名稱空間/類型創建類的新實例? – Birk 2009-06-12 13:52:54

回答

1

我想通了,並張貼我的代碼以供參考。在挖掘關於類/對象工廠的網頁時(感謝RBarry),我在System.Reflection類中發現了幾個對Activator.CreateInstance()的引用。

Imports Microsoft.VisualBasic 
Imports System.Runtime.CompilerServices 
Imports System.Reflection 

Public Module enviornmentUtilities 
    <Extension()> _ 
    Public Function SessionSinglton(ByVal objType As Type) As Object 
     Dim sessionName As String = objType.FullName.ToString 
     If Not HttpContext.Current.Session(sessionName) Is Nothing Then 
      HttpContext.Current.Trace.Write(HttpContext.Current.Session(sessionName).ToString) 
      Return HttpContext.Current.Session(sessionName) 
     Else 
      Dim ss = Activator.CreateInstance(objType) 
      HttpContext.Current.Session(sessionName) = ss 
      Return ss 
     End If 
    End Function 
End Module 

這將讓您從任何類基於會話的單不要求在新的方法參數(這工作不要求這一點)

爲了測試我做了一個簡單的類:

Public Class HasNew 
     Public FreshInstance As Boolean = True 
     Public Sub New() 
      HttpContext.Current.Trace.Warn("This Class has a new method") 
     End Sub 
     Public Sub CheckFreshness() 
      If FreshInstance Then 
       HttpContext.Current.Trace.Warn("Fresh HasNew Instance") 
       FreshInstance = False 
      Else 
       HttpContext.Current.Trace.Warn("NotFresh HasNew Instance") 
      End If 
     End Sub 
     Public Shared Function type() As Type 
      Return GetType(HasNew) 
     End Function 
     Public Shared Function SessionSinglton() As HasNew 
      Return GetType(HasNew).SessionSinglton 
     End Function 
    End Class 

你會注意到兩個公共共享方法type()和SessionSinglton它調用上述擴展方法。

有了這兩個功能加入,我們有三種方式來啓動會話Singlton證明這裏:

Dim HN As HasNew 

HN = HasNew.SessionSinglton 
HN.CheckFreshness() 

HN = HasNew.type.SessionSinglton 
HN.CheckFreshness() 

HN = GetType(HasNew).SessionSinglton 
HN.CheckFreshness() 

此文件的跟蹤輸出如下:

This Class has a new method 
Fresh HasNew Instance 
NotFresh HasNew Instance 
NotFresh HasNew Instance 

的在對SessionSinglton方法的第一次調用中訪問類new()方法,隨後的調用反映該實例實際上是從內存中提取的。

我希望這可以幫助別人在未來。

+0

+1非常好的解決方案。我會保持這一點。 – RBarryYoung 2009-06-12 21:09:15

1

如果你使用泛型,你可以做New T()。你的SessionSingleton也返回「對象」類型,需要投射。我沒有測試這個,但它應該工作。

Imports Microsoft.VisualBasic 
Imports System.Runtime.CompilerServices 
Imports System.Reflection 

Public Module enviornmentUtilities 
    <Extension()> _ 
    Public Function SessionSinglton(Of T As {Class, New})(ByVal obj As T) As T 
     Dim sessionName As String = obj.GetType.Name 
     If Not HttpContext.Current.Session(sessionName) Is Nothing Then 
      HttpContext.Current.Trace.Write(HttpContext.Current.Session(sessionName).ToString) 
      Return HttpContext.Current.Session(sessionName) 
     Else 
      Dim ss = New T() 
      HttpContext.Current.Session(sessionName) = ss 
      Return ss 
     End If 
    End Function 
End Module 
相關問題