How to add handlers to events for a late-bound object?

I have a .NET dll which is being referenced in a VB.NET application.

I'm referencing this object using late binding as we want the application to cope if the dll is missing from the run directory. This will happen in certain cases as not everyone who runs the application will need or have access to the dll. Please don't tell me to just give everyone the dll, that's not what we want.

The problem is that one of the objects I referencing from the dll raises a few events which I want to handle in the application.

I've defined the object variable like so:
Private m_objOptions As Object

and I'm initialising it like so:
m_objOptions = New Compass.clGetOptions()

I'm trying to add a handler to one of the events like so:
AddHandler m_objOptions.Status, AddressOf Message

but I'm getting the error
'Status' is not an event of 'System.Object'

Can anyone help me resolve this?
How do I add a handler to a late-bound object?

Many Thanks,
Who is Participating?

[Webinar] Streamline your web hosting managementRegister Today

arif_eqbalConnect With a Mentor Commented:
Try Typecasting

AddHandler CType(m_objOptions, Compass.clGetOptions).Status, AddressOf Message

Jeff CertainCommented:
You'll have to look at the Compass object... but the error seems to indicate that you are not using a valid event name in your AddHandler statement. I'd guess you need something like StatusChanged.
AddHandler m_objOptions.StatusChanged, AddressOf Message

Is Compass your own class?
janineoAuthor Commented:
Compass is my own class, and the event is called Status.

The AddHandler line compiles with no problem when I use early binding, i.e I declare the object like so:
Private m_objOptions As Compass.clGetOptions

Free Tool: Subnet Calculator

The subnet calculator helps you design networks by taking an IP address and network mask and returning information such as network, broadcast address, and host range.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Jeff CertainCommented:
There's the question of why, exactly, you're late-binding that control. Having to guess, I'd say that it is because you have several classes with a status event, but want to use them interchangably at run-time based on certain settings?
why do u want to use the late binding?

Private m_objOptions As Object
m_objOptions = New Compass.clGetOptions()

The above code is not a latebinding code.

You know the type of the object is "Compass.clGetOptions" then why are u declare "Private m_objOptions As Object" instead of "Private m_objOptions As Compass.clGetOptions"?

Private m_objOptions As Compass.clGetOptions
the above line is just a declaration.

We can create a latebinded object in the following ways

Private m_objOptions As Compass.clGetOptions
m_objOptions = DirectCast( CreateObject("Compass.clGetOptions") , Compass.clGetOptions)

Private m_objOptions As Compass.clGetOptions
m_objOptions = DirectCast( Activator.CreateInstance(gettype("Compass.clGetOptions")) , Compass.clGetOptions)

then add the event handler


janineoAuthor Commented:
arif_eqbal: Using CType didn't work - the IDE complained about needing a singular object with AddHandler.

Chaosian: Not quite. What we're doing is an experiment. We want to create a sort of 'Add-in' for the application. If the dll is in the run directory then certain options are available in the application, and if it's not then the user never knows they are missing.

vinodhsomasekharan: I want to do late binding as using early binding - declaring objOptions as Compass.clGetOptions causes errors when the dll is missing from the run directory, which I want to handle gracefully.
The error I get is
File or assembly name Compass, or one of its dependencies, was not found.
I don't think you can do this.  Although you can add to an Object's properties and methods by late-binding it to a specific subordinate class - e.g.

    Private m_objOptions As Object

        m_objOptions = "abcd"
        Dim s As String = m_objOptions.substring(0, 1)

- so far as I can tell it remains stuck with the events dictated by its original declaration.

I'll be happy to be proved wrong, but ...

Jeff CertainConnect With a Mentor Commented:
Okay.... why not declare the object as the correct type, and only add the handler if the conditions are met? This gets you around the late-binding issue.

Roger... interfaces :)
janineoAuthor Commented:

Thanks, but that didn't work.
The form didn't open, probably because the m_objOptions variable is a class-level variable and defining it as something that it can't find killed the form.
I'm getting the same 'File or assembly name Compass, or one of its dependencies, was not found.' error.

janineoAuthor Commented:
Sorry, I meant Chaosian, not Roger!
janineoAuthor Commented:
I've been googling the problem, and I've seen references to using OLE Callback.
I have no idea what this is, or if it's suitable in my case.
Can anyone enlighten me to this?
janineoAuthor Commented:
I've just found out that using CType did work - as far as compilation anyway. I must have typed it wrongly before.

I think I may not be late-binding properly - In VB6 I would use CreateObject, I'm guessing that it's different in VB.NET?
Not just assigning an variable of type Object to some other value?

I'm still getting the 'File or assembly name Compass, or one of its dependencies, was not found.' error.
It may have to do with a control from the library that is created on the form. How would I late-bind this?
janineoAuthor Commented:
Okay, I think I'm getting there.

I've defined an Object at the class level, and then used
to create an instance of the control.

However I'm still getting the 'assembly not found' error during the method where I'm adding an event handler to the control using
AddHandler CType(myCtl, Compass.usrControl).Status, AddressOf myCtl_Status

So I think I'm almost back to my original problem!
I can get it to compile now, but it doesn't run properly if the dll is missing.
Maybe I can just try and catch the error, though I'm not sure how.
I'm getting the JIT error box even though I've got a try-catch in the method.

I'll think on it more tomorrow.
Well, Typecasting should work with AddHandler
If you can resolve the 'File or Assembly not found' issue it would hopefully work
Your assembly "Compass" does it refer any other DLL/Assembly ?
Check if the dependencies of the referenced assembly are fine
Check if the required files are available in the path that the Runtime looks into for locating the files
This will help you know where all the runtime looks for dependencies

Jeff CertainCommented:
I still wonder if you wouldn't be better to instantiate it as a specific type only if the client has purchased the appropriate'd avoid all the late binding... which, in this case,seems like a waste of effort since you only ever bind to one type anyhow.

Or did I miss something?
janineoAuthor Commented:

It's an initial experiment. Our company is part of a multinational organisation and here in the UK we've created an application that is used by the UK branch.

The UK has just been merged into a 'UK, Europe, and Africa' group and our IT director is talking about 'exporting' our application into Europe & Africa.

However, we don't want to give them our source code for them to mess around with, and equally we don't want to build and support a different version of the app for each country, as each countries apps will have different requirements.

So we're looking into breaking the app down into wholely enclosed sections that we can package up as dlls and send out to the other countries for them to integrate without really knowing much about them.

We're also considering building our own 'IDE' for creating the finished app, hence the 'ignore the section if the dll isn't there' issue I'm having. It's entirely possible that the people doing the 'building' will have very little programming knowledge - like excel macros or something.

As I said, it's all an experiment - can we do this, should we do this, will it be more hassle than it's worth?
janineoAuthor Commented:
It works!

Would you believe that moving the code that only gets executed if the dll is there into it's own function and calling that instead stopped the unhandled exception from occuring?

It's exactly the same code, called in exactly the same place, it's just wrapped up in a different function.

Well, that's VB.NET for you. Must have something to do with how it does the compilation.

I'll split the points between arif_eqbal and Chaosian as you both helped with your comments, though the type casting did solve the original issue.

Many Thanks,

All Courses

From novice to tech pro — start learning today.