When you reference a .NET class that exposes events, and you switch on the WithEvents property, C/SIDE creates the event triggers for you. If you later want to update the reference to the .NET class, for whatever reason (like, there is a newer version of the assembly), updating the reference will actually delete the event triggers with all the code in them.
To be fair to this non-feature, at least it warns you politely:
This is not something you experience once in a geologic era. When you are developing your own assemblies, this will happen fairly often – as often as you add or remove events to/from your classes, and you want to reflect that in the Development Environment. Or as often as you increase the version of your assembly.
Unfortunately, there is no way in the Development Environment to update the reference while actually retaining the event triggers or code in them.
But still, there is a way, and a fairly easy way at that.
First, consider this C# class:
Doesn’t save the world, but makes for a simple example.
Declare a DotNet variable of this class type in C/AL, set its WithEvents property, and here’s what you get:
Let’s add some flesh to the bone and see if the event fires:
Run this ingenious piece of code, and see that it works:
So far, so good. Now imagine that there is a newer version of the assembly, and you have to update the variable reference. Attempting to do so from the Development Environment will lose your precious code from the existing event trigger.
So here’s what you do:
- Export the object as a text file.
- Open the object in Notepad (or something of the sort), look up the variable declaration, and update it to the new version. Then save the file.
- Import the file, and then compile the object.
For the step 2), this is what your code (the variable declaration part) might look like originally:
ClassWithEvents@1000 : DotNet "'Mauritius.Rocks, Version=220.127.116.11, Culture=neutral, PublicKeyToken=904e723ed03ae71d'.Mauritius.Rocks.ClassWithEvents" WITHEVENTS;
After the update, it might look like this:
ClassWithEvents@1000 : DotNet "'Mauritius.Rocks, Version=18.104.22.168, Culture=neutral, PublicKeyToken=904e723ed03ae71d'.Mauritius.Rocks.ClassWithEvents" WITHEVENTS;
If the assembly didn’t merely change the version number, and there are – say – new events in the class, you can still solve the problem easily. Imagine that your new version of C# class looks like this:
Still not saving the world, but getting there one step at a time.
Absolutely the only way in C/AL to get this new event (SomeOtherEvent) to show up is to update the reference, and still when you do, it will lose the code. Still, you can use the text file to handle this. Simply copy the original event trigger:
EVENT ClassWithEvents@1000::SomeEvent@8(sender@1001 : Variant;e@1000 : DotNet "'mscorlib, Version=22.214.171.124, Culture=neutral, PublicKeyToken=b77a5c561934e089'.System.EventArgs");
… and paste it below, then update the signature to match what C# declares:
EVENT ClassWithEvents@1001::SomeOtherEvent@9(sender@1001 : Variant;e@1000 : DotNet "'mscorlib, Version=126.96.36.199, Culture=neutral, PublicKeyToken=b77a5c561934e089'.System.EventArgs");
MESSAGE('Other event fired');
Just make sure to increase both IDs specified after @s. Compile, run, and voilá.
Now, this took several manual steps, and was a bit dirty to play directly with C/AL text files and all. Nice thing is, you could easily automate this (both reference updating, and event trigger updating) through PowerShell. Now, if I wasn’t in Mauritius, enjoying this wonderful view from the balcony, I would have probably bothered enough to write that scriptlet for you. But I’ll leave it for another time, and simply sit and relish the sunset… Tough life, I know, but someone’s gotta do it.