VB.Net Initialising a class using System.Reflection and System.Type to create a session based singleton extension method - asp.net

I have had several occasions recently to access a specific class several times over a relatively small time frame.
So I've been storing the value of the class in Session and trying to access it on page load, if it's not available creating a new instance and storing that in session.
So instead of constantly replicating the same code for different classes on different pages I'm trying to create an extension method to do this for me.
I want to use it like this
Dim objName as MyClass
objName.SessionSingleton()
So far this is what I have for my extension method:
<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
I'm stuck on what to do when I make my new instance of my class (it would have to have a New() sub)
I'm not sure where to go from here... or even if this is the best way to do it.

I figured it out and am posting my code for reference. While digging thru pages about Class/Object Factories (thanks RBarry) I found several references to Activator.CreateInstance() in the System.Reflection Class I came up with this.
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
This will let you create a session based singleton from any class that does not require parameters in the new method (which isn't required for this to work)
To test I made a simple Class:
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
You'll notice the two Public Shared Methods type() and SessionSinglton which calls the above extension method.
With those two functions added we have three ways to initiate the Session Singlton demonstrated here:
Dim HN As HasNew
HN = HasNew.SessionSinglton
HN.CheckFreshness()
HN = HasNew.type.SessionSinglton
HN.CheckFreshness()
HN = GetType(HasNew).SessionSinglton
HN.CheckFreshness()
The Trace Output for this file is as follows:
This Class has a new method
Fresh HasNew Instance
NotFresh HasNew Instance
NotFresh HasNew Instance
The classes new() method is accessed on the first call to the SessionSinglton method and subsequent calls reflect that the instance is in fact being pulled from memory.
I hope this helps someone else in the future.

If you used generics you could just do New T(). Also your SessionSingleton returns "object" type, requiring casting. I did not test this but it should work.
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

Related

Lazy .NET. How to use it with list of objects?

I have a webservice that implements a lazy handler that handles queries on db and fills list of structure. This is made to avoid to read from DB.
Basically I have:
Public Class Lazy_Handler
Implements IDisposable
Private lToRet As New List(Of External_Widget)
'[... other lists to be read from DB the first time]
Private Shared ReadOnly lazy As Lazy(Of Lazy_Handler) = _
New Lazy(Of Lazy_Handler)(Function() New Lazy_Handler())
Public Shared ReadOnly Property Instance As Lazy_Handler
Get
Return lazy.Value
End Get
End Property
Public Function list_of_external_widget() As List(Of External_Widget)
Try
If lToRet Is Nothing Then
lToRet = New List(Of External_Widget)
End If
If lToRet.Count > 0 Then
Return lToRet
End If
lToRet = New List(Of External_Widget)
'... QUERY FROM DB HERE, DETAILS OMITTED
Return lToRet
Catch ex As Exception
Purge("link_of_external_widget:" & ex.Message)
Return New List(Of External_Widget)
Finally
DBOperazioni.CloseConn()
End Try
End Function
End Class
so from my website I call something like
Dim list_of_external_widget As List(Of Lazy_Handler.External_Widget) = _
Lazy_Handler.Instance.list_of_external_widget()
I expect that the first time the lazy is created, then the query is executed. After that, no more lazy creations and no more queries on DB.
I'm right?
It works well, but sometimes (I don't know where) there something that becomes Nothing and I get error. What could it be?
Thank you

Create a dataContract in separe file problem

Hi I need to create a class for return the data in WCF service. I followed the web at 5 simple steps to create your first RESTful service. However I get the error for . I searched the web and add the System.Runtime.Serialization.DataContractSerializer, Would someone tell me what should do. I am using VS2015 as the tool to build it. Thanks.
Imports System.Runtime.Serialization
Imports System.Collections.Generic
Imports System.Runtime.Serialization.DataContractSerializer
<DataContract>
Public Class Locations
<DataMember>
Public Property LocationName As String
<DataMember>
Public Property LocationID As Integer
End Class
Could you please share the error details with me?
As you know, we usually use the datacontract to transmit the complex data type which could be recognized by the client-side and server-side. so that the data could be serialized and transmitted normally between different platforms.
For the restful web service in WCF, we need to use the Webhttpbinding build the data channel and add the Webhttpbehavior to the service endpoint.
I have made a demo, wish it is useful to you.
Server-side.
Imports System.Runtime.Serialization
Imports System.ServiceModel
Imports System.ServiceModel.Description
Imports System.ServiceModel.Web
Module Module1
Sub Main()
Dim uri As New Uri("http://localhost:900")
Dim binding As New WebHttpBinding()
binding.CrossDomainScriptAccessEnabled = True
binding.Security.Mode = WebHttpSecurityMode.TransportCredentialOnly
binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.None
Using sh As New ServiceHost(GetType(MyService), uri)
Dim se As ServiceEndpoint = sh.AddServiceEndpoint(GetType(IService), binding, uri)
se.EndpointBehaviors.Add(New WebHttpBehavior())
sh.Open()
Console.WriteLine("Service is ready")
Console.ReadLine()
sh.Close()
End Using
End Sub
<ServiceContract([Namespace]:="mydomain")>
Public Interface IService
<OperationContract>
<WebGet(ResponseFormat:=WebMessageFormat.Json)>
Function SayHello() As List(Of Product)
End Interface
Public Class MyService
Implements IService
Public Function SayHello() As List(Of Product) Implements IService.SayHello
Dim result = New List(Of Product)() From {
New Product With {
.Id = 1,
.Name = "Apple"
},
New Product With {
.Id = 2,
.Name = "Pear"
}
}
Return result
End Function
End Class
<DataContract([Namespace]:="mydomain")>
Public Class Product
<DataMember>
Public Property Id() As Integer
<DataMember>
Public Property Name() As String
End Class
End Module
Client.
$(function(){
$.ajax({
type:"GET",
url:"http://10.157.18.188:900/sayhello",
dataType:"jsonp",
success:function(d){
$.each(d,function(i,o){
console.log(o.Id);
console.log(o.Name);
})
}
})
})
Result.
Here is an official sample
https://learn.microsoft.com/en-us/dotnet/framework/wcf/feature-details/how-to-create-a-basic-wcf-web-http-service

class modules in asp.net file system website

I have a class module in my App_code folder.
Private _connection As MySqlConnection
Private _connStr As String
Public Function Connect(dbName As String) As Boolean
Try
_connStr = "Database=" & dbName & ";" & _
"Data Source=192.16.0.1;" & _
"User Id=user;Password=pass"
_connection = New MySqlConnection(_connStr)
_connection.Open()
_connection.Close()
Return True
Catch ex As Exception
_connection = Nothing
Return False
End Try
Return False
End Function
I usually program in webform apps. Why can't I access this function from my aspx code behind pages? I added the import statement for the class. If i make that function shared I cant have those private variables.
I call the function in my aspx lik so;
If Connect(dbName) then....
That gets me an error "non shared member requires an object reference"
You need to add the keyword "Shared" to the method signature, like so:
Private Shared _connection As MySqlConnection
Private Shared _connStr As String
Public Shared Function Connect(dbName As String) As Boolean
This is because otherwise you have instance class members, not static members. The compiler error message is quite self-explanatory.
if you look at this example works:
Public Shared Function example123(ByVal USER As Integer, ByVal Section As String, ByVal ACTION As String) As Boolean
you assign a function shared so you can see it from outside the class
I hope you work

VB.NET: Use Class Name as Expression

I'm not sure if this is possible but I would like to associate a class name reference to a shared member method / property / variable. Consider:
Public Class UserParameters
Public Shared Reference As Object
Public Shared Function GetReference() As Object
Return Reference
End Function
End Class
In another part of the program I would like to simply call UserParameters and have it return Reference either by aliasing GetReference or the variable directly.
I am trying to emulate the Application, Request, or Session variable:
Session(0) = Session.Item(0)
Any suggestions would be greatly appreciated.
You can't return an instance member from a static method directly (the static method can't access instance members because it isn't instantiated with the rest of the class, only one copy of a static method exists).
If you need to setup a class in such a way that you can return an instance from a static method you would need to do something similar to the following:
Public Class SampleClass
Private Sub New()
'Do something here
End Sub
Public Shared Function GetSample() As SampleClass
Dim SampleClass As SampleClass
SampleClass = New SampleClass
SampleClass.Sample = "Test"
Return SampleClass
End Function
Private _SampleString As String
Public Property Sample As String
Get
Return _SampleString
End Get
Private Set(ByVal value As String)
_SampleString = value
End Set
End Property
End Class
Public Class SampleClass2
Public Sub New()
'Here you can access the sample class in the manner you expect
Dim Sample As SampleClass = SampleClass.GetSample
'This would output "Test"
Debug.Fail(Sample.Sample)
End Sub
End Class
This method is used in various places in the CLR. Such as the System.Net.WebRequest class. where it is instantiated in this manner in usage:
' Create a request for the URL.
Dim request As WebRequest = WebRequest.Create("http://www.contoso.com/default.html")

User Controls Importing Problem (asp.net)(vb)

I have this class that contains vars for db connection;
Imports Microsoft.VisualBasic
Imports System.Data.SqlClient
Imports System.Web.Configuration
Public Class DBVars
Public Shared s As String
Public Shared con As String = WebConfigurationManager.ConnectionStrings("NMMUDevConnectionStr").ToString()
Public Shared c As New SqlConnection(con)
Public Shared x As New SqlCommand(s, c)
Dim r As SqlDataReader
End Class
I import this to my page like this;
Imports DBVars
I'm then able to access these vars from my page.
But if I try to import them into a user control using the same method the variables are not available. Am I making an error or is this expected?
Thanks.
Make sure you're accessing them in your usercontrol like so:
Dim useMe As String = DbVars.con
and not something like
Dim x As DbVars = new DbVars()
dim useMe As String = x.con
You need to do this because you've declared them as Shared (static) and not as Instance variables.

Resources