AddIns - The Fragile Nature of Workspace Configuration

Workspace configuration settings allow an administrator to set specific values for your add-in based on the workspace that it's placed on. For example: if you have a control with a label you could expose the label text as a configuration setting so that administrators could change it without needing you to re-compile your add-in. String, bool and int types are supported by the attribute.

The simplest of configuration settings can be created by adding the following to your class that implements IWorkspaceComponent or IWorkspaceComponent2:


However, this example doesn't show how that value can be used. To do that we can implement the get and set accessors on the property and pass the value into our control where it can then push the values into the appropriate labels:
We can now see how values can be passed up to our UI layer during both workspace configuration time and during the loading of a record.

There is however an interesting bug. The code below does not work:


It took me far more time to figure out the difference than it should have. In the launcher I've called the property ThisDoesNotWork but in the control I've called the property DoesNotWork. This difference in naming is what breaks the config setting. I discovered the problem by hooking up a debugger and watching the property on the launcher get hit twice during workspace setup (once for the default value and once for the value that it was configured to) but only once during the loading of a record (default value). Confusing right? Here is what's happening: the add-in framework loads the add-in, looks at the names of all of the properties exposed as configuration values and then stores a lookup between the add-in and the settings, but during the loading of the record it stores the control as the lookup value instead of the IWorkspaceComponent class. So they're defined in the Component but set on the Control. This is a bug. RightNow product development assumes that your component actually implements Panel or UserControl and then just returns itself when GetControl() is called, so the two objects are actually the same. However, I like to have a bit more separation between my UI layer and my AddIn setup so the two objects aren't the same.
There are 3 solutions:
  1. Keep the same file structure but be very careful when naming properties: gives separation of logic but is fragile
  2. Implementing IWorkspaceComponent as a partial class of your Control: gives both separation of logic and conforms to RNT assumptions
  3. Implement UserControl or Panel on your WorkspaceComponent: conforms to RNT assumptions but doesn't separate UI and AddIn logic
  4. ...harass RightNow to fix the bug and then implement it any way you see fit...
I'm yet to start writing my add-ins this way but solution #2 seems the most elegant.

Full source is available on Bitbucket under / AddIns / WorkspaceConfig /

Comments

Hey Jack,

that is great info, as I have been banging my head over this for some time now. However you mentioned that RN assumes the component is returned. In many of their examples they also return a control, so that would suggest that this is absolutely not as designed. Unless their examples are wrong ofcourse..

thanks again,
Bastiaan

Hey Jack,

I am not completely sure how your #2 solution would look like? If you have the UserControl as a partial class of your IWorkspaceComponent2 class how can you then launch the Usercontrol from the IWorkspaceComponent2 class?

Bastiaan

Zircon - This is a contributing Drupal Theme
Design by WeebPal.