2009-06-11 4 views
1

J'ai récemment eu plusieurs occasions d'accéder à une classe spécifique plusieurs fois sur une période relativement courte. J'ai donc stocké la valeur de la classe dans Session et essayé d'y accéder au chargement de la page, si elle n'est pas disponible en créant une nouvelle instance et en la stockant dans la session.VB.Net Initialisation d'une classe à l'aide de System.Reflection et System.Type pour créer une méthode d'extension singleton basée sur une session

Donc, au lieu de constamment répliquer le même code pour différentes classes sur des pages différentes, j'essaye de créer une méthode d'extension pour le faire pour moi.

Je veux l'utiliser comme ceci

Dim objName as MyClass 

objName.SessionSingleton() 

Jusqu'à présent, c'est ce que j'ai pour ma méthode d'extension:

<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 

Je suis bloqué sur ce qu'il faut faire quand je fais mon nouveau instance de ma classe (il faudrait avoir un nouveau() sous)

Je ne sais pas où aller à partir d'ici ... ou même si c'est la meilleure façon de le faire.

+0

Je pense que vous avez besoin d'usines d'objets pour vos classes. – RBarryYoung

+0

Je pense que cela pourrait être sur la bonne voie ... c'est un nouveau concept pour moi alors je fais des recherches.Si je comprends correctement les Class/Object Factories, je dois savoir à l'avance ce que sont les classes et il n'y a pas moyen de créer une nouvelle instance d'une classe basée sur son namespace/type. – Birk

Répondre

1

Je l'ai compris et je poste mon code comme référence. Tout en creusant à travers les pages à propos de Class/Object Factories (merci RBarry) j'ai trouvé plusieurs références à Activator.CreateInstance() dans le System.Reflection Class je suis venu avec cela.

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 

Cela vous permettra de créer un singleton à base de session d'une classe qui ne nécessite pas de paramètres dans la nouvelle méthode (qui ne sont pas nécessaires pour que cela fonctionne)

Pour tester, je fait une simple classe :

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 

Vous remarquerez les deux méthodes Shared Public Methods() et SessionSinglton qui appelle la méthode d'extension ci-dessus.

Avec ces deux fonctions supplémentaires, nous avons trois façons de lancer la session Singlton démontré ici:

Dim HN As HasNew 

HN = HasNew.SessionSinglton 
HN.CheckFreshness() 

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

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

La sortie de trace de ce fichier est comme suit:

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

Le La méthode new() de classes est accessible lors du premier appel à la méthode SessionSinglton et les appels suivants indiquent que l'instance est en fait extraite de la mémoire. J'espère que cela aidera quelqu'un d'autre à l'avenir.

+0

+1 Très belle solution. Je vais garder ça. – RBarryYoung

1

Si vous utilisiez des génériques, vous pourriez simplement faire un nouveau T(). De plus, votre SessionSingleton retourne un type "objet", nécessitant un casting. Je n'ai pas testé cela mais ça devrait marcher.

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 
+0

Ceci est intéressant, je vais devoir faire d'autres recherches sur l'utilisation de génériques. Je ne peux pas comprendre comment utiliser cette extension ... en utilisant mon exemple de classe j'ai essayé: Dim HN As HasNew HN = HasNew.SessionSinglton2(): La référence à un membre non partagé nécessite une référence d'objet. Aussi Dim HN As HasNew HN = HN.SessionSinglton2(): Référence d'objet non définie sur une instance d'un objet. – Birk

+0

Eh bien, oui, les méthodes d'extension nécessitent une instance du type qu'elles étendent, donc ce que vous essayez de faire ne fonctionnera pas. – epitka

Questions connexes