Jump to content

Using the Factory pattern with OpenG Builder namespacing


Recommended Posts

post-7603-1234223602.png?width=400



So I was planning on working AQ's Factory Pattern into my project when I ran into a snag. Since OGB (OpenG Builder) creates namespaces by changing filenames, I can't set the path to the desired class in the factory vi without prior knowledge of the namespace to be used. Does anyone have a good general solution to this problem? There are a few options I can think of in order of increasing complexity:
  • Hardcode: Since I do happen to know the namespace to be used, I can simply include it as part of the filename in the source code. (i.e. Generic Plugin\Generic Plugin__namespace.lvclass)
    Pros: This is the fastest solution in the short term and easy to implement.
    Cons: Writing code that will break based on a build setting seems like a bad idea. This method could become a maintenance headache, especially for the developer who inherits my code.
  • Implement Path Wildcards: Build a library that allows file system wildcards in path constant. The class source code can simply include a wildcard in the appropriate location. (i.e. Generic Plugin\Generic Plugin*.lvclass)
    Pros: Fairly robust without being too difficult to implement.
    Cons: Potential for lots of special case exceptions. (What if there are no matches? What if there are multiple matches?)
  • Use a Translation File: Have the build process create an ini file that includes key-value pairs correlating the original name with the post-build name that is distributed as part of the build. When I need a vi's post-build name I'd simply look it up in the ini file.
    Pros: At first glance this method seems to be universally robust. The namespacing can be changed arbitrarily without breaking the class' built code. This could possibly be used by programs that consume the built class, meaning namespace changes don't break dependent applications.
    Cons: I'd have to write a OGB script to perform the translation during the build, which I'm not sure is possible without altering OGB source code. I'd probably also write a small library that looks up and performs the translation transparently. Encapsulation leads me to want to include the translation library as part of the class source code, but that ties class functionality to a file created during the build process.

I'm leaning towards the wildcards as it seems to offer a decent balance of dev time, robustness, and flexibility. Has anyone ever dealt with this issue before? How did you solve it?

Link to comment

Another option: Stop using OpenG namespaces and instead put the whole kit and kaboodle into a LV Library to provide namespacing. If you do that, your paths aren't changed at all. You can still use OpenG to namespace that top level library if you so desire, but all the stuff inside that library retains its original path and filename.

Link to comment

QUOTE (Aristos Queue @ Feb 9 2009, 06:17 PM)

Another option: Stop using OpenG namespaces and instead put the whole kit and kaboodle into a LV Library to provide namespacing. If you do that, your paths aren't changed at all. You can still use OpenG to namespace that top level library if you so desire, but all the stuff inside that library retains its original path and filename.

Actually I do put all my code in LVLibs or Classes. However, my project currently includes a dozen different classes and lvlibs I have built and distributed to myself over the past two years as reuse code packages using OpenG namespacing. Rebuilding them without the namespaces means I have to go through all the class hierarchies and replace the OG namespaced vis with non-OG namespaced vis. Been there, done that, no hurry to experience it again. (What I wouldn't have given for a 'Select Replacement VI...' dialog box hotkey combo.)

In any event, the class I was referring to in the orig post is a distributed reuse class, meaning it is (IMUO) essentially required to namespace the .lvclass by changing the filename. Why? Different class names for source and distributed code allows me to have both loaded in memory at the same time, which makes developing, debugging, and fixing my reuse code much easier. Even if I removed the namespacing from member vis I'm still facing the original issue.

I'm not quite to the point where I trust Labview enough to remove OG namespaces from my member vis. Using them works reasonably well and I'm not anxious to run into an unforeseen brick wall somewhere down the road by removing them. Some call it prudence, some call it wisdom... I call it fear of the unknown. (File system restrictions on duplicate file names is one potential obstacle, though not one that affects me directly as I distribute each class/lvlib to its own directory.) I'm almost there... just not quite.

Link to comment

QUOTE (Daklu @ Feb 9 2009, 10:59 PM)

In any event, the class I was referring to in the orig post is a distributed reuse class, meaning it is (IMUO) essentially required to namespace the .lvclass by changing the filename. Why? Different class names for source and distributed code allows me to have both loaded in memory at the same time, which makes developing, debugging, and fixing my reuse code much easier. Even if I removed the namespacing from member vis I'm still facing the original issue.

With exactly identical file names, you can have both your source and distribution in memory at the same time. You load your source in one project and your distrib in another project. They are thus in isolated application instances. LV 8.5 and later will even detect if you try to load your distrib into the same project as your source and will say "this could potentially create cross linking, would you rather open this in a separate project?"

Every LV 8.x release has included features designed to eliminate the need for prefixing. If you're still needing it, then clearly there is something that the R&D team does not understand about LabVIEW and how our users are using it, because there's general agreement on the team that the tools exist now (8.6) such that you shouldn't have any reason to keep using prefixes. This should probably move to a new thread, rather than hijack Daklu's original question about how to deal with this, but a detailed list of why, between the project application instance isolation and the library namespacing, prefixing for distribution is still necessary.

Link to comment

QUOTE (Daklu @ Feb 10 2009, 02:11 AM)

OpenG builder post-build files have the info you need (pre-build names and post-build names.

QUOTE (Aristos Queue @ Feb 10 2009, 11:35 AM)

Every
LV
8.x release has included features designed to eliminate the need for prefixing. If you're still needing it, then clearly there is something that the R&D team does not understand about LabVIEW and how our users are using it, because there's general agreement on the team that the tools exist now (8.6) such that you shouldn't have any reason to keep using prefixes. This should probably move to a new thread, rather than hijack Daklu's original question about how to deal with this, but a detailed list of why, between the project application instance isolation and the library namespacing, prefixing for distribution is still necessary.

The options in OpenG builder are a little bit more advanced:

  • Prefix or postfix
  • Optional random namespace
  • Next release of OpenG builder allows to namespace the library files only
  • Optional random password
  • Pre and postbuild VIs (to alter description for instance)
  • Version info on source distribution builds
  • Pure G version info

Ton

Link to comment

QUOTE (Ton @ Feb 10 2009, 05:02 AM)

The options in OpenG builder are a little bit more advanced:
Oh, I know that the OpenG distribution has a lot of useful features. I'm only addressing the one feature of renaming all your VIs/libraries when publishing. The goal was to make such hoop jumping unnecessary.

But your list does raise a related question: Why the heck would you want a random namespace??? I can understand a GUID or a version or somesuch, but random?

Link to comment

QUOTE (Aristos Queue @ Feb 10 2009, 04:28 PM)

But your list does raise a related question: Why the heck would you want a random namespace??? I can understand a GUID or a version or somesuch, but random?

Uhm, I even checked to see if the feature was really available and not made up by me.

But yes the feature is available, but I have never used it, maybe just for kicks.

Ton

Link to comment

QUOTE (Ton)

The OpenG application palette have VIs to 'unmangle' or 'mangle' file names.

'Mangle' is close, but it still requires prior knowledge of the namespace. I was hoping for a more general solution given an unknown OpenG style namespace. I suppose the best solution would to use a vi reference and pull the path from that. If I decide to migrate away from OG namespaces completely I might just skip the whole thing and hardcode the namespace for now.

QUOTE (Ton)

The next release of OpenG builder will optionally only mangle the name of the library not the files inside the libraries (like AQ proposed)

You can already do that. Turn off namespaces on the General tab and on the Destinations tab set a custom namespace for the .lvclass or .lvlib.

QUOTE (Aristos Queue)

This should probably move to a new thread, rather than hijack Daklu's original question about how to deal with this, but a detailed list of why, between the project application instance isolation and the library namespacing, prefixing for distribution is still necessary.

Better a productive, informative, slightly off-topic discussion than no discussion at all. Besides, that discussion is over... your topic is more interesting. :)

QUOTE (Aristos Queue)

If you're still needing it, then clearly there is something that the R&D team does not understand about LabVIEW and how our users are using it...

One word: "Incorrectly." ;)

The way Labview namespacing is tied to the library name seems like an odd decision since it creates potential implementation obstacles that apparently make name mangling the safer route to take, even if it isn't a completely satisfying solution. Maybe these aren't real issues at all and only exist in my mind...

First is the potential for name collisions. I might have a Microwave class designed to capture debug output from the oven while the cafeteria has a Microwave class for automated cooking and the RF Lab has a Microwave class for testing wireless communications. My application needs to test the microwave oven while reusing code from the automated cooking process and pelting the oven with high intensity radiation. What is the preferred way to use all three classes in my project? Should I copy the code for each class and give them each unique names? Should I wrap each class in its own library and give the library a unique name? This seems like a hack since I'm not using the library to bundle related functionality (it's already bundled in the class) but only for the purpose of establishing a namespace. Using the library wrapper method, what namespace do the class' member vis have? LibraryName.ClassName.VIName? Or just LibraryName.VIName?

Second is the inability to create namespaces in a hierarchy that is logical for the organization. I want to be able to create a namespace that makes sense in my working environment. (<MegaBucksInc.ConsumerProductsDivision.HouseholdApplicances.MicrowaveOvens.Test.Microwave.lvclass>) The other microwave classes could be namespaced at <MegaBucks.Services.Cafeteria.Microwave.lvclass> and <MegaBucks.Communications.Wireless.Microwave.lvclass>. We had developers attempt to create a hierarchical namespace by nesting LVLibs but that proved to be unworkable.

Is there a reason namespaces aren't implemented as a library property that is independent of the file name, perhaps settable by right-clicking on the library in the project window?

QUOTE (Aristos Queue)

You load your source in one project and your distrib in another project.

Couple questions rooted in my incomplete understanding of application instances:

  • What happens when you load a library outside a project context, such as by opening a .lvlib file from the OS file system? Is there a default application instance that is used?
  • After doing that, what happens if I then try to load another library with the same name outside a project context? Is another 'default' application instance spawned with a different name?
  • How does Labview deal with this situation: An application is built with a static link to a "Honda" class to provide automobile functionality. Later on another "Honda" class is dynamically linked (since it cannot be statically linked) to provide lawnmower functionality. Does Labview automatically coerce the Honda lawnmower class into a different namespace so it can share the same application instance? Does Labview open it in a separate application instance and automatically provide communication between the two? Does the behavior change when moving from the dev environment to the run-time environment?

Link to comment

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.