.Net assembly withevents

FishermanFisherman Member Posts: 456
All -

I'm a .Net programmer at heart, so I can't resist the opportunity to get back into my roots :)

I've written a .Net assembly that logs onto and streams XML data to one of our partner company's web sites. It then waits for a response, and parses the response xml to determine if the data was accepted. I've tested the assembly using a test form in the .Net IDE, and all is well there.

I've regasm'd it with the /tlb and /codebase switches, and I am able to create an automation variable with no issue in Navision.

What I haven't quite figured out is the WithEvents property for a global. I've set it to "Yes", which I thought would cause the events from my assembly to appear as triggers in my codeunit, but I'm not seeing them. Am I missing something? Will Navision handle events from a .Net assembly?

Thanks.

Comments

  • kinekine Member Posts: 12,562
    I haven't tested the events yet, but may be some problem with visibility of the events? (public, interface, old COM Id etc.)
    Kamil Sacek
    MVP - Dynamics NAV
    My BLOG
    NAVERTICA a.s.
  • SteveOSteveO Member Posts: 164
    Just off the top of my head...
    You need to create a seperate interface for the events and then implement that interface by using
    [ComSourceInterfaces(interfacename)]
    This isn't a signature, I type this at the bottom of every message
  • Dennis_DecoeneDennis_Decoene Member Posts: 123
    edited 2006-10-26
    This would be nice to know, I havn't yet needed this but I can think of situations where I could have used it.

    If you find a solution? Could you share how you've cracked it?
  • chridochrido Member Posts: 12
    I haven't tried it but that's the theory. Taken from http://www.codeproject.com/dotnet/comin ... ntsClassic
    Essentially, a COM object that supports outgoing interfaces, implements the IConnectionPointContainer interface. A client that wants to receive event notifications does a QI on the COM object for the IConnectionPointContainer interface to see if it supports outgoing interfaces. If the QI fails, then the object does not support events. If the QI succeeds, the client calls the FindConnectionPoint method (could also call EnumConnectionPoints) on the IConnectionPointContainer interface by passing it the IID of the outgoing interface. If such an interface is supported, the client receives back an IConnectionPoint interface pointer corresponding to the outgoing interface. It then calls the IConnectionPoint::Advise method and passes to it, the sink object's IUnknown pointer. The COM object adds this IUnknown pointer to its map to keep a list of the sink objects that have subscribed for notifications. The client gets back a cookie from the COM object that it can subsequently use to revoke event notifications. When the COM object needs to raise events, it iterates through the map, gets a list of all the sink object interface pointers and calls the corresponding event methods on the outgoing interface (implemented by the sink object). When a client no longer desires to receive notifications, it removes itself from the object's map by calling the IConnectionPoint::Unadvise method by passing it the cookie that it received earlier on the IConnectionPoint::Advise call.

    Obviously you have been able to stream to a .net dll (I'm currently fighting with that, maybe you can have a look at this, that would be very nice ;)http://www.mibuso.com/forum/viewtopic.php?t=14386
  • FishermanFisherman Member Posts: 456
    I've figured out the events - I had been trying to follow the C# example that I found on mibuso for event handling. It has explicit COM interface declarations. I wasn't able to get that working (I'm using VB.Net and was getting a compilation error), but after a bit of thinking, I replaced my class with a COM Class. My events are appearing now in Navision.

    chrido - I wasn't planning on passing a stream from Navision to .Net, or vice versa (although it would be useful - oh how I wish I could save Navision reports to a stream - I'd just splat it into a memory stream)- I'm just passing the data (as an string) to the dll and waiting on the response. When i get the response, i'm raising one of a few events indicating what the results were, and whether I got my ID from the remote system (it's an ASN system).
  • FishermanFisherman Member Posts: 456
    Thanks to all for the help on this. I've managed to solve this and it's working beautifully.

    As I indicated before - I recreated my class as a COM Class using the New Item wizard. It managed the COM GUIDs in the background, and works great. Then, I just had to register the .dll with regasm and I'm off.

    chrido - I did run across an issue, and I think i know where you're coming from. I'm having to build a large XML document based on the sales order. The document is not well-formed XML, but it is a customer-prescribed standard, so I have to go with it. I wanted to use an XML Port, but couldn't find a way to do so that didn't involve a lot of file I/O, so I built the file in memory using text constants. That brought about another issue - passing a BIGTEXT variable to an external COM interface. I tried to write to an OUTSTREAM and then pass that stream to the dll, but it didn't cast correctly. Since I didn't want to get bogged down in custom COM marshalling, I just added a class-level string to my COM Class, and provided a public method called ADDTEXT which just appends to the class-level string.

    If you figure out how to perform the marshalling for the IStream objects, I would like to know.

    Thanks.
  • FishermanFisherman Member Posts: 456
    if you're working in .Net 2.0 - then this might be helpful. They've added managed support for the IStream interface in the framework.

    http://msdn2.microsoft.com/en-us/librar ... tream.aspx
  • CenTCenT Member Posts: 12
    Anyone actually able to create a .NET Assembly with events that create eventtriggers in navision when setting the automation property to WithEvents "True"?

    Some sample code could be useful if you have done so in the past.
    Thanks.
  • FishermanFisherman Member Posts: 456
    I was able to, and it works beautifully.

    Code examples would be pointless, to be honest, because there's nothing special what I did.

    I created a new Class Library and added a new item. I chose the COM Class type, which created a new class. If you use the COM Class, then the IDE manages all of the COM interop, GUIDs, delegates, etc..., for what you create in your class.

    After I compiled it, I moved it to my target machine, ran "regasm Mydll.dll /tlb /codebase" (the codebase isn't really necessary, but I'm doing strong-named assemblies, so I chose to use it).

    Then, all I had to do was create a new GLOBAL (important - it has to be global) automation variable in a codeunit, point it to my dll, and change the WithEvents property to TRUE. Voila - .net events in C/AL.

    by the way - as for the .Net 2.0 stream example I posted earlier - it doesn't work. Apparently, even the ComClass.Istream type in the 2.0 framework shows up as IUnknown in Navision. I'm going to try some hackery with the ADO stream from the 2.7 type library to see if I can force the interop.
  • toortoor Member Posts: 52
    Hi there,

    can you please post an example?

    I've written a com class in c# wich has some events. I can see the events in navision, but if an event fires, navision hung up.

    So i really like to see a working example :-)


    regards
    tobias
  • FishermanFisherman Member Posts: 456
    toor -

    I can't post my code, because it is sensitive, but I will try to work up a simple example and post it for you.
  • toortoor Member Posts: 52
    Hi Fisherman,

    thank you very much for your help.

    I'm very anxious to see the code.

    regards
    tobias
  • FishermanFisherman Member Posts: 456
    edited 2006-12-01
    www.geocities.com/rws5344/witheventsdemo.zip

    Maybe this will help

    This is very, very simple - just a hello world. You will have to run regasm from the .Net SDK on the .dll file. Then, import the .fob into a test Navision server.
  • toortoor Member Posts: 52
    Hey guys,

    the dispidattribute is the trick. I don't no why (havn't read the docu, yet), but it works.

    @Fisherman: Your link doesn't work. I get a "Page unavailable" error.


    So, thank you very much again Fisherman and aohlfsen.


    regards
    tobias
  • FishermanFisherman Member Posts: 456
    Sorry - I'm not sure what is happening. If you click the link, it doesn't work, but if you copy and paste it into your browser, then it is...
  • chridochrido Member Posts: 12
    http://www.codeproject.com/dotnet/comin ... tionPoints

    Good Article for understanding events and also some samples.

    greetings
    chris
Sign In or Register to comment.