Lawo / ember-plus

Ember+ control protocol - Slick and free for all!
https://github.com/Lawo/ember-plus/wiki
Boost Software License 1.0
111 stars 41 forks source link

Change Root Node during runtime? #94

Closed GRieber closed 5 years ago

GRieber commented 5 years ago

Hello all,

I wrote a consumer using ember-plus-sharp sdk. Everything works fine. My consumer works against a Nova29 provider. The provider in Ruby, Sapphire and Crystal for accessing the system matrix (...and only this...) are identical but the root node is different ("Nova29", "Ruby"...). My question is: Is there any way to change the root node during runtime, after reading a registry key, by example?

My consumer is declared by this:

Public con As Consumer(Of Nova29Root)

con = Await Consumer(Of Nova29Root).CreateAsync(client, 30000, childrenRetrievalPolicy:=ChildrenRetrievalPolicy.All)

NotInheritable Class Nova29Root
       Inherits Root(Of Nova29Root)

       <Element(Identifier:="Nova29")>
       Public Property Nova29 As Nova29

End Class

NotInheritable Class Nova29
        Inherits FieldNode(Of Nova29)

        <Element(Identifier:="Matrices")>
        Public Property Matrices As Matrices

End Class

...and so on.

So it should be possible to modify the Nova29Root class to use either Nova29, Ruby or Sapphire.

Any idea by anyone?

Thanks and best regards

Gerhard

mkeuck commented 5 years ago

Hello Gerhard, I have two ideas that might work, but I also have to test them myself.

The first one is to use a mix of static and dynamic model, but I do not know if it is possible to use the root element as dynamic part. I will check that this afternoon or tomorrow.

The second idea is to query the device type first, and create a second Consumer based on the result. The device type is located in the root/identity node. It probably requires three root node classes, which are all the same, except that the Identifier is set to the value of the associated device type. But then, I am not sure how to declare the Consumer class, since it requires a base class derivindg from Root.

So, unfortunately, it seems to be not that easy.

GRieber commented 5 years ago

Hello Marius, Thanks for answering. I guessed, that it would not be that easy... my special wishes :-) So let's wait the results of your testings.

Best regards

Gerhard

mkeuck commented 5 years ago

Hello Gerhard, it really seems to be impossible to have dynamic root nodes. I tried the CollectionNode<T> class, but it did not work. I found another way that seems to work: you can declare an element as optional, so you can declare the properties within the root node all of the same type, but all with different names:

    sealed class Device : Root<Device>
    {
        [Element(Identifier = "Nova29", IsOptional = true)]
        public Router RouterN29 { get; private set; }

        [Element(Identifier = "Sapphire", IsOptional = true)]
        public Router RouterSapphire { get; private set; }
    }

You then only have to check which property was set to a valid instance. I hope it works.

Best regards, Marius

GRieber commented 5 years ago

Hello Marius, such an easy solution - but it works!!!

This is my code in VB:

NotInheritable Class Device
        Inherits Root(Of Device)

        <Element(Identifier:="Nova29", IsOptional:=True)>
        Public Property RouterN29 As Nova29

        <Element(Identifier:="Ruby", IsOptional:=True)>
        Public Property RouterRuby As Nova29

        <Element(Identifier:="Crystal", IsOptional:=True)>
        Public Property RouterCrystal As Nova29

        <Element(Identifier:="Sapphire", IsOptional:=True)>
        Public Property RouterSapphire As Nova29

    End Class

Thank you again for your great help!!

Best regards

Gerhard