LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Multiple .net assembly versions and LVOOP issue?

Solved!
Go to solution

Hi Guys,

 

I was trying to create a design idea with some LVOOP programming on a .net assembly, and ran into a problem.

 

Design idea:

  • the .net assembly has multiple versions (let's call them net1, net2, net3...netN).
  • Use class inheritance (let's call them class1, class2, class3...classN)
  • Each classN inherits from class N-1, and uses the standard .net constructor to create a reference to netN called referenceN, this way I have a class for every version of the .net assembly. Class N inherits all the N-1 .net assembly methods for all previous versions, and then I write the new methods particular to netN
  • classN stores referenceN in the private data of the first ancestor via an accessor
  • Dynamical dispatch is used to pull the correct reference at runtime, and run whatever methods are required

Problem:

We ran into a roadblock because it seems that even though in the .net constructor you can select multiple assemblies via the select constructor, after you do so on the more than one class in the project, every .net constructor in the project defaults to whichever one was first selected. That of course torpedoes the design idea above...

 

Any chance this is a known problem with a known solution?

 

Thanks,

 

-Wavepacket

 

 


------------------------------------------------------------------------------------

Please join the conversation to keep LabVIEW relevant for future engineers. Price hikes plus SaaS model has many current engineers seriously concerned...

Read the Conversation Here, LabVIEW-subscription-model-for-2022
0 Kudos
Message 1 of 13
(1,356 Views)

I've not done much with .net so perhaps there is a valid reason, but I'm curious as to why you would make each class a child of the previous class. Shouldn't they be siblings using dynamic dispatch to determine which of the siblings should be run? 

0 Kudos
Message 2 of 13
(1,336 Views)

@johntrich1971 wrote:

I've not done much with .net so perhaps there is a valid reason, but I'm curious as to why you would make each class a child of the previous class. Shouldn't they be siblings using dynamic dispatch to determine which of the siblings should be run? 


That might be a mistake (which could be worth discussing). I think I'd run into the same main issue though with .net constructor/multiple versions o the same dll not being able to be simultaneously constructed.

 

At the moment, I'm simply renaming the .net dlls by appending their version number, and then selecting the renamed ones. After selecting more than 1, it seems that LabVIEW constructors automatically change to the first one that I selected.


------------------------------------------------------------------------------------

Please join the conversation to keep LabVIEW relevant for future engineers. Price hikes plus SaaS model has many current engineers seriously concerned...

Read the Conversation Here, LabVIEW-subscription-model-for-2022
0 Kudos
Message 3 of 13
(1,324 Views)

Renaming the assembly file doesn't change the qualified name of the assembly (ie it's unique ID) stored in metadata. It impacts initial loading of assemblies from disk but, once loaded, the runtime will re-use that assembly in memory if requested for the same qualified name. Quite probable the behavior you are seeing is based on that.

 

https://docs.microsoft.com/en-us/dotnet/standard/assembly/names 

https://docs.microsoft.com/en-us/dotnet/framework/deployment/how-the-runtime-locates-assemblies 

 

If you want to confirm this behavior, you can try loading in each assembly using a tool like ILSpy or Reflection methods in the Framework to observe the fully qualified name of each of your renamed assemblies. I'm guessing the name will be the same for all of them, regardless of the  filename.

 

If you want your versions to be unique, you need to change the metadata version. However, as a general rule, it is a bad idea to load different versions of the same effective assembly into the same context as it can lead to type conflicts at runtime (version 1 of "MyType" isn't the same as version 2). 

 

Maybe you can elaborate on what your goal / use case is here. There's almost always an alternate approach that is more robust or more sustainable.

Message 4 of 13
(1,310 Views)

We had a similar issue to this and unfortunately the only solution we found was quite a pain to use.  You basically have to make a "service" program for each .NET version, compile it to an EXE, and then send messages over TCP/IP or some other messaging method that works in LabVIEW EXEs compiled separately.

 

This might or might not work for you, because it won't allow .NET references to be passed over messaging... you have to convert the .NET stuff into "by data" values, send them over your messaging system, and then use them there.  So if your DLL needs you to pass an output object into the rest of your code, you may be out of luck.

0 Kudos
Message 5 of 13
(1,297 Views)

Is the requirement to have different assemblies a hard one? Because usually if you use inheritance to implement new versions, what is done is to add the new class to the same assembly with a new class name.

 

You still end up with assemblies for each version but a higher version assembly includes the lower version class implementations too.

 

It seems what you are trying to do is to implement some sort of plugin architecture with different versions. But that is not a good idea. Either use plugins to implement different implementations that all conform to the same base class interface or use versioning by adding a new class implementation version to the existing assembly.

Rolf Kalbermatter
My Blog
0 Kudos
Message 6 of 13
(1,284 Views)

@rolfk wrote:

Is the requirement to have different assemblies a hard one? Because usually if you use inheritance to implement new versions, what is done is to add the new class to the same assembly with a new class name.

...


This quote is referring to inheritance within the dlls? 

 


@rolfk wrote:

...

 

It seems what you are trying to do is to implement some sort of plugin architecture with different versions. But that is not a good idea. Either use plugins to implement different implementations that all conform to the same base class interface or use versioning by adding a new class implementation version to the existing assembly.


Well, to be honest I'm not sure exactly how to phrase what I'm trying to do in the plugin architecture. So the dll has multiple versions, but I anticipate that each of these versions only have one class -- I thought would marry up well with inheritance within classes. That might be a mistake.


------------------------------------------------------------------------------------

Please join the conversation to keep LabVIEW relevant for future engineers. Price hikes plus SaaS model has many current engineers seriously concerned...

Read the Conversation Here, LabVIEW-subscription-model-for-2022
0 Kudos
Message 7 of 13
(1,241 Views)

@tyk007 wrote:

Renaming the assembly file doesn't change the qualified name of the assembly (ie it's unique ID) stored in metadata. It impacts initial loading of assemblies from disk but, once loaded, the runtime will re-use that assembly in memory if requested for the same qualified name. Quite probable the behavior you are seeing is based on that.

 

https://docs.microsoft.com/en-us/dotnet/standard/assembly/names 

https://docs.microsoft.com/en-us/dotnet/framework/deployment/how-the-runtime-locates-assemblies 

 

...


That sounds likely, I'm open to changing the software design decision.

 


@tyk007 wrote:

...

 

Maybe you can elaborate on what your goal / use case is here. There's almost always an alternate approach that is more robust or more sustainable.


So the dll has multiple versions written by someone else, let's presume each version is just a new version of the same .net class within that dll. Initially I thought that would marry up well with inheritance within labVIEW classes b/c I wanted to maintain backwards compatibility, so if I really had to use an older version of the dll, I could just change which child class I initialized with. 

 

That software architecture (assigning a new inherited LabVIEW class whenever a new dll version but with same qualified name comes out) might be a poor choice. Is there a better way? 

 


------------------------------------------------------------------------------------

Please join the conversation to keep LabVIEW relevant for future engineers. Price hikes plus SaaS model has many current engineers seriously concerned...

Read the Conversation Here, LabVIEW-subscription-model-for-2022
0 Kudos
Message 8 of 13
(1,238 Views)

The problem here is that you have two different inheritance chains. One on .Net level with classes inheriting from each other that also reside in different DLLs and then you want to have another inheritance chain in LabVIEW that calls these inherited classes. That's a bit of a double arched architecture that sooner or later bites in its own tail.

 

You should have either inheritance on .Net level or on LabVIEW level but not both at the same time. Personally if you control the .Net interface I would include all implementations of a version in the same assembly and add a factory class to it. This factory class does nothing more than returning you the correct class interface. In its default constructor it returns whatever is the highest version its DLL implements. An optional parameterized constructor can be used to request a specific version.

 

But the big question is if you really want to go to such a length. Plugins often sound like a great idea, but their implementation is not trivial and fraught with lots of smaller and bigger stones on the path, and some of them can be very painful.

 

And plugins should NOT inherit from each other. They should inherit from a common interface class, nothing more. And you need some kind of class factory, preferably on the level that also defines the base class interface. Anything else is asking for trouble in the longer run. 

Rolf Kalbermatter
My Blog
0 Kudos
Message 9 of 13
(1,233 Views)

@rolfk wrote:

The problem here is that you have two different inheritance chains. One on .Net level with classes inheriting from each other that also reside in different DLLs and then you want to have another inheritance chain in LabVIEW that calls these inherited classes. That's a bit of a double arched architecture that sooner or later bites in its own tail.

....


I fear I've misled you. So far as I'm aware, the .net dll does not have inheritance within itself. My understanding right now is that the .net dll has multiple versions, but it's multiple versions of a single class.


------------------------------------------------------------------------------------

Please join the conversation to keep LabVIEW relevant for future engineers. Price hikes plus SaaS model has many current engineers seriously concerned...

Read the Conversation Here, LabVIEW-subscription-model-for-2022
0 Kudos
Message 10 of 13
(1,228 Views)