Calling method of class in hub using SignalR - signalr

I have hub class with some methods, which are called by client without problems. But what to do, if I want to call method of class in hub's property, for example:
Class MyHub
Inherits Hub
Sub HubMethod()
End Sub
Property SC As New SimpleClass
End Class
Class SimpleClass
Sub DoNothing()
End Sub
End Class
I want to do something like myHubInstance.Invoke("SC.DoNothing"). Is it even possible?

You can't do that. SignalR server discovers hubs using Reflection by checking if a type is derived from IHub.

Related

Connection String in Constructor

Right now I'm able to establish a connection within my class by calling it in each method by doing the following.
Dim sConnectionString As String = ConfigurationManager.AppSettings("Blah")
'Establish connection with db
Dim cnSqlConnection1 As New SqlConnection(sConnectionString)
Only problem is that I have to call it in each method. I was told that it was better to create a constructor for the class nad have the connection string it uses passed into the constructor.
Here's my attempt but can't seem to figure out since I'm still unable to reach it in the method.
Public Sub New(ByVal sConnectionString As String)
sConnectionString = ConfigurationManager.AppSettings("Blah")
End Sub
What is the best way to do it? Thanks in advance.
You should store the passed connectionstring in a global variable available in all of your class methods
Public Clas MyClass
Private String gs_conString
Public Sub New(ByVal sConnectionString As String)
gs_conString = sConnectionString
End Sub
Public Sub AMethod()
'Establish connection with db
Dim cnSqlConnection1 As New SqlConnection(gs_conString)
.....
End Sub
.....
End Class
Of course this means that every time you create an instance of this class you need to pass the connection string to your constructor
Dim cl As MyClass = new MyClass(ConfigurationManager.AppSettings("Blah"))
So it is probably better to use the constructor to extract the connection string automatically everytime you create an instance
Private String gs_conString
Public Sub New()
gs_conString = ConfigurationManager.AppSettings("Blah")
End Sub
Go with the first option, putting the connection string in the constructor. You don't want your class to depend directly on <appSettings>.
Your class's interface should indicate what dependencies it has. When you put the connection string in the constructor, the class says, "Hey, I need a connection string!"
If the class calls <appSettings> then a user of the class has no way of knowing that the class expects to find a connection string there unless they open your code and read it. If they don't know that the connection string belongs there then they'll get a null reference exception with no explanation.
That raises the question - whatever class creates your class, where does it get the connection string so it can pass it to the constructor? Dependency injection is the answer. It enables you to write classes that way then "wire it up" so that the correct arguments get passed to your constructors.

can I pass an aspx page class to a subroutine?

Here's what I'd like to do: Let's say I have a page named "foo.aspx". The class is called "foo". On the page is a checkbox named "bar". I want a subroutine to update that checkbox.
So what I want to write is something like:
In foo.aspx.vb:
partial class foo
... whatever ...
dim util as new MyUtility
util.update_checkbox(me)
In MyUtility
public sub update_checkbox(foo1 as foo)
foo1.bar.checked=true
end sub
But this doesn't work, as Visual Studio doesn't accept "foo" as a class name. Why not? Is there a magic namespace on it, or something else I have to do to identify the class besides say "foo"?
(And yes, I realize that in this trivial example, I could just pass in the checkbox, or move the one line of code into the aspx.vb, etc. My real problem involves setting a number of controls on the form, and I want to be able to do this in a class that has subtypes, so I can create an instance of the proper subtype, then just call one function and set all the controls differently depending on the subtype.)
Update
NDJ's answer works. For anyone else dropping by here, let me add that I was able to do something a little more flexible than his suggestion. I was able to create a property that returns the control itself, rather than some attribute of the control. Namely:
public interface ifoo
readonly property bar_property as literal
end interface
partial class foo
inherits system.web.page
implements ifoo
Public ReadOnly Property bar_property As Literal Implements ITest.bar_roperty
Get
' assuming the aspx page defines a control with id "bar"
Return bar
End Get
End Property
...
dim util=new MyUtility()
util.do_something(me)
...
end class
public class MyUtility
public sub do_something(foo as IFoo)
foo.bar_property.text="Hello world!"
foo.bar_property.visible=true
end sub
end class
This is a bit of a pain as you have to create an interface, and then create a property for each control that you want to be able to manipulate, but it does appear to work.
If there's a way to make the aspx class itself public, this is all unnecessary baggage in most cases. (It might be valuable if you have multiple pages that have controls that you want to manipulate in the same way.) But I can't figure out how to do that.
You can do this, but there are a few hoops to jump through.
Using your example...
If you create an interface with a Boolean property, then implement it in your page, then you can pass the interface about and changing the property will automatically change the checkbox. i.e.
interface:
Public Interface IFoo
Property Bar As Boolean
End Interface
implementation:
Partial Class _Foo
Inherits Page
Implements IFoo
Public Property Bar As Boolean Implements IFoo.Bar
Get
Return Me.CheckBox1.Checked
End Get
Set(value As Boolean)
Me.CheckBox1.Checked = value
End Set
End Property
Then some handler just needs to accept the interface:
Public Module SomeModule
Public Sub SetValues(foo As IFoo)
foo.Bar = True
End Sub
End Module
and the caller from the page passes itself:
Protected Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
SomeModule.SetValues(Me)
End Sub
You can expose the checkbox as a public property on the page. I don't write in VB.net, but it would look something like this in C#:
Can someone convert this to VB.Net?
public bool MyCheckBoxSetting
{
get { return mycheckbox.Checked; }
set { mycheckbox.Checked = value; }
}

How to store and access per call data in WCF

I'm trying to set up some WCF services that are connected and pass a custom HTTP header from service to service.
That is my client call ServiceX, which calls ServiceY, which writes to the DB.
They are originally called from a Silverlight 5 client in some cases, other cases from an ASP.NET web app.
I implemented IClientMessageInspector and IDispatchMessageInspector to pass the header from service to service, and in the DispatchMessageInspector I wrote the header to an implementation of IExtension(Of OperationContext) (see below).
However, I wanted this data only to exist for the duration of the call, but it seems to be sticking around in the services under certain circumstances as I keep seeing the same header data repeated in different calls.
Ultimately, I want to be able to pass a custom header to a WCF service, persist it only while that call exists, send it to the next service in the header, and wipe out that service instance. Am I wrong in my thinking that using a PerCall WCF service setup and OperationContext is the right way to do that?
Here is my implementation of IExtension(Of OperationContext). The auditTransactionId is the thing I want to pass in the service. As well, the Current() property is where I keep seeing existing data:
Imports System.ServiceModel
Public Class CustomOperationContextExtension
Implements IExtension(Of OperationContext)
Private ReadOnly m_items As IDictionary(Of String, Object)
Private m_auditTransactionId As String
Private Sub New()
m_items = New Dictionary(Of String, Object)()
End Sub
Public ReadOnly Property Items() As IDictionary(Of String, Object)
Get
Return m_items
End Get
End Property
Public Property AuditTransactionId() As String
Get
Return m_auditTransactionId
End Get
Set(value As String)
m_auditTransactionId = value
End Set
End Property
Public Shared ReadOnly Property Current() As CustomOperationContextExtension
Get
If (OperationContext.Current IsNot Nothing) Then
Dim context As CustomOperationContextExtension = OperationContext.Current.Extensions.Find(Of CustomOperationContextExtension)()
If context Is Nothing Then
context = New CustomOperationContextExtension()
OperationContext.Current.Extensions.Add(context)
End If
Return context
End If
Return Nothing
End Get
End Property
Public Sub Attach(owner As OperationContext) Implements IExtension(Of System.ServiceModel.OperationContext).Attach
End Sub
Public Sub Detach(owner As OperationContext) Implements IExtension(Of System.ServiceModel.OperationContext).Detach
End Sub
End Class
EDIT:
When I say that data is sticking around, I mean that when I call Current in a new service call I expect the Extensions list to be empty (in the code below in the Current() property), but there is always an existing instance of CustomOperationContextExtension there already that is left over fro a previous call. I'm not sure under which circumstances this happens.

Implicit reference to object under construction is not valid when calling another constructor

I am trying following Within my MVC Controller:
Private ProductRepoitory As IProductRepository
Sub New()
Me.New(New productsRepository(New ModelStateWrapper(Me.ModelState)))
End Sub
Sub New(ByVal repo As productsRepository)
ProductRepoitory = repo
End Sub
However this line throws following Error message:
Me.New(New productsRepository(New ModelStateWrapper(Me.ModelState)))
Implicit reference to object under construction is not valid when calling another constructor
I understand, I am calling a Constructor within a Constructor, and other Constructor expects a parameter, its the parameter part where it is failing.
Removing "me" does not help, I need to pass my Controller's ModelState as a parameter to ModelStateWrapper Class, any other workarounds?
Before you call Me.New(), your object hasn't been constructed yet.
Therefore, you can't access Me.
You can't use Me.ModelState when creating a constructor chain with Me.New. The alternative is to create an 'initialize' method like this:
Private ProductRepoitory As IProductRepository
Sub New()
Me.Initialize(New productsRepository(New ModelStateWrapper(Me.ModelState)))
End Sub
Sub New(ByVal repo As productsRepository)
Me.Initialize(repo)
End Sub
Private Sub Initialize(ByVal repo As productsRepository)
Me.ProductRepoitory = repo
End Sub
Also note, unless Me.ModelState is a property and the getter method does some sort of initialization of the value, then when you pass it into the Initialize method, Me.ModelState will be null. It's likely this kind of pattern will cause some problems for you later on, so you may want to consider refactoring your code a bit.

Reference to a non shared member requires an object reference

I have added one class under namespace BusinessLogics.
I have inherited System.Web.UI.Page to class and showing error as 'end expected' in
System.Web.UI.Page
Namespace BusinessLogics
Public Class BllUploadImages Inherits System.Web.UI.Page
End Class
End Namespace
How can i remove my error.Can anybody help?
The Server property is an instance property of the Page class, so you need a Page instance in order to access it. There are a couple of different ways for you to solve this.
It looks like objDesign is of a type that inherits System.Web.UI.Page. Perhaps you can use that instance to invoke the MapPath method:
serverPath = objDesign.Server.MapPath(".") + "\"
One other approach is to fetch the current HttpContext object and use the Server property of that object:
serverPath = HttpContext.Current.Server.MapPath(".") + "\"

Resources