CAB module confugiration problem

Topics: CAB & Smart Client Software Factory
Sep 19, 2006 at 9:23 PM
originally posted by: ching100

Suppose I created a new CAB module, it is possible to be loaded by SHELL with the modification of ProfileCatalog.XML. We don't need to recompile the whole application.
But if this new CAB module has some configurations, where to store this values? In App.cfg or in another XML file? Who has the integrated and standard approach to deal with configuration issues? Never forget that the deployment problem.
Sep 20, 2006 at 6:40 AM
originally posted by: JKraft4PIT

"where to store this values? In App.cfg"

That is where i would put it since you can have a app.cfg for each module and a resource file.

"in another XML file?"

Right now i have resources and configurations build for each module seperately (like i mentioned above) but will hopefully soon have a configuration service to be able to save and load from where ever. I plan on using the .Net 2.0 System.Configuartion calsses.
Sep 20, 2006 at 4:42 PM
originally posted by: ching100

Thank you for your reply. I prefer the App.cfg approach too. But the problem is : Each time when I publish a new ClickOnce version, it will replace the *.exe.cfg ( same as App.cfg ) , all user changes of properties are gone. How could you deal with this deployment and configuration issue?
Sep 21, 2006 at 5:55 AM
originally posted by: JKraft4PIT

Well I haven't had to worry about this problem yet, but I didn't relise this problem existed.
But I am just using the app.config right now as my configuration and will be building my own config service anyways. (I have a config service but it just uses App.Config)

I did find this posting on MSDN Forums.

It says that you can have App settings which will change with releases (ReadOnly) and you can have UserSettings (Read/Write).
When you update the app settings will be updated but the users settings willl stay the same unless teh user hasn't changed the setting.
This is how I undeerstand that last bit:(I will be using sort of code, not writing XML Config files)

*Each version is a click once version, so the data is what you Defaulted it to.

DBString = "..\DB\TheDataBase.mdf" 'ReadOnly app setting
BackgroundColor = red 'User Setting, Read and Write
Title = "My Cool Click Once App" 'User Setting Read and Write

User changes the background color to Blue.

DBString = "..\DB\TheOtherUpdatedDataBase.mdf"
BackgroundColor = red
Title = "The Click Once App"

So now what happens?

The background color stays the same (Blue)
The DBString will be updated.
The Title Will be updated to "The Click Once App".

Hope that helps, and point out if i am wrong or miss informed :))
Sep 21, 2006 at 8:50 PM
originally posted by: ching100

Thanks a lot for your solution. It sounds great help for me. Just one more question: After we deployed the Shell application, how can we import a new CAB module without rebuilding the whole Shell application? As what you mentioned, the new cab module can consume the service to have its configurations, but how it works? Could you show me the details? Thank you.
Sep 22, 2006 at 5:57 AM
originally posted by: JKraft4PIT

Now remember this is just how i am thinking it would go down. I havne't been able to test anything yet.

So are you using ClickOnce deployment?
How are you loading the module? Profile Catalog? Programically?

"How can we import a new CAB module without rebuilding the whole Shell application"

First off you should just be able to use the module, the only thing is that the Module woudl have to consume your "Constants" module that hosts all your workspace names and event subscriptions/prublications and things. So You may have to recompile that module to work with your constants. But other than that it shoudln't effect you shell, like the name suggests it is just a shell.

anyways, I load my modules using the Profile catalog so all i would do is add the module to the roles in the profilecatalog.xml that would use it. The main app "Shell" wouldn't have to recompile but I would still do a release using ClickOnce even though it is only a single file change (Proflie Catalog).

But if you are wondering about "Zipping" a module to a user so they can use it. I would assume they could just edit the Profile Catalog, but if you have a smart client setup the profile catlog should be Encrypted so this can't happen.

"As what you mentioned, the new cab module can consume the service to have its configurations, but how it works?"

Well the configuaration service would be like anyother service you consume. Except it would be created in the very root workitem since all modules/workitems/presenters would consume it. Then you would use it like any other configuration service, just doing reads for configuration information.

"Could you show me the details? "

<ServiceDependency> _
Public WriteOnly Property SetConfigurationSErvice as ConfigurationService
Set (Byval Value as ConfigurationService)
_ConfigService = Value
End Set
End Property

Public Function GetWindowLayout as ConfigurationService.Layout
if _ConfigService IsNot Nothing then
Return _ConfigSerivice.GetWindowLayout(Me)
Return ConfigurationService.Default
End Function

All this does is inject my configuration service, then I have a simple fungtion to get some configuration information. This is most likely in a presenter some where to get the layout for a form for a view.

Hope this helps,
Sep 22, 2006 at 9:32 PM
originally posted by: ching100

Thank you for your reply.
"The main app "Shell" wouldn't have to recompile but I would still do a release using ClickOnce even though it is only a single file change (Proflie Catalog). "
Is it true for the new cab module who consumes the configuration service to add some configuration items in app.cfg? If so, the app.cfg will be changed and how can you use the newly added user settings, for example, Properties.Settings.Default.XXX( newly added item) will not work. How can your configuration service add new user settings items in app.cfg? Thanks in advance.
Sep 23, 2006 at 6:26 AM
originally posted by: JKraft4PIT

App.cfg is individual to each module(dll) so your module would be only using Properties.Settings.Config.XXXX.

So that means the service would effect only one module. And if you are adding configurations to the service then that module that the service is in would have to be rebuilt and released also.
Sep 25, 2006 at 4:16 PM
originally posted by: ching100

Although each module can contain App.cfg, it couldn't be useful because only Shell's app.cfg will be used. In addition, I didn't find Properties.Settings.Config.XXXX. I just found Properties.Settings.Default.XXXX. Could you show me the details? Thank you in advance.
Mar 18, 2008 at 4:23 PM
You are correct here, Only the Shell's app.config is ever used when you write for properties with "application" scope. It seems like User scope properties do work, but they don't use the app.config file at all.

If the shell.exe.config file doesn't contain the key, the default values are used, and they are hard coded in the Settings.Designer.cs making the whole system useless.

Does anyone have any guidance for creating a per module configuration system?
Mar 18, 2008 at 4:24 PM
Edited Mar 18, 2008 at 4:26 PM
Mar 19, 2008 at 1:06 AM
We've just had to address the same issue in trying to separate our Shell completely from the modules running inside of it.
We have a requirement for different teams to target the same instance of the shell, so have removed any module specific configuration from shell.exe.config to avoid headaches trying to merge multiple teams configuration into one shell.exe.config.

I found that the .Net configuration system is not at-all friendly with composite applications that want to use 'per module' configuration.

More specifically:

The 'settings' stuff is pretty useless as it needs that information in Shell.exe.config. Short of creating new app-domains to load a 'module.dll.config' file in you're stuffed (see for a thread). For me creating new app-domains seems like massive overkill just to configure my application.

We use WCF for services. Try configuring WCF without using the <system.serviceModel> configuration section. Not so easy. I failed to find an easy way to take a configuration from 'module.dll.config' and turn it into a set of end-points. Even though there are lots and lots of WCF configuration classes I couldn't find the way in. So we resorted to creating bindings in code... Easy... Until one of our endpoints created a WCF behaviour which was an internal class. The only way we got this to work was by using reflection to create the behaviour. Thanks for that MS!!!

Our "solution" is

  1. Ship a 'module.dll.config' file with a module.
  2. Provide a helper class which returns a Configuration object given an Assembly instance.
  3. Instruct teams not to use a Settings class but to use <appSettings> instead.
  4. Instruct teams to create a static configuration class which offers strong typed access to the <appSettings>


internal static class ModulesConfiguration
  public static bool LocalConfigurationSetting
    get { return Boolean.Parse(_config.AppSettings.Settings["localConfigurationSetting"].Value); }

It's not pretty but it has got us per module configuration without having to hijack shell.exe.config.

My advice - if you are only ever going to ship 'your' modules with the shell, and never will have a requirement for 'Team B's' modules inside your shell, then put all your configuration in shell.exe.config!

Hope that helps,