Changing App Server Endpoint at Runtime

Changing App Server Endpoint at Runtime

Old forum URL: forums.lhotka.net/forums/t/11548.aspx


rlhiggin posted on Wednesday, August 22, 2012

Hey folks,

I am working on a "check out" concept in our application currently. For this concept I need the ability to change the app server that our client is pointing to at run time. Right now I have implemented this context switch by isolating my wcf client configuration into a separate config file that is referenced by setting the configSource attribute for the system.serviceModel/client section in the main config file. When I change context I simply point the configSource attribute at a file that contains either the remote endpoint or the local endpoint, save the main config file, and then call System.Configuration.ConfigurationManager.RefreshSection("system.serviceModel/client") to update the configuration cache. My testing is showing that the configuration change is working successfully, however the data portal does not seem to be able to pick up this change even after telling it to reset the proxy and channel factory.

Is the data portal supposed to be able to pick up this change automatically or will I need to implement something custom to tell it to not to cache its proxy and always pull it from configuration. If I need to implement something custom, what would be the best approach for trying to set this up?

JonnyBee replied on Thursday, August 23, 2012

No, CSLA will not catch that change in web.config.

You may however change the

setttings in your code.

Here's the code from ApplicationContext.DataPortalUrlString:

    public static string DataPortalUrlString
    {
      get
      {
        if (_dataPortalUrl == null)
        {
          _dataPortalUrl = ConfigurationManager.AppSettings["CslaDataPortalUrl"];
        }
        return _dataPortalUrl;
      }
      set
      {
        _dataPortalUrl = value;
      }
    }

rlhiggin replied on Wednesday, August 29, 2012

JonnyBee,

Thank you for the reply. I tried messing with the ApplicationContext to see if I could get the DataPortal to recognize the changes I was making to my configuration file. Nothing I tried would work. After looking into it further, the real issue seems to be how the default WCF ChannelFactory handles reading endpoint data from configuration.

My goal was to have the client app talk to its server database via a NetTcpBinding connection to the remote app server when connectivity is available and to talk to its local database via a NetNamedPipeBinding connection to a local app server when it needs to "check out" some subset of data that will be synced back later.

I wanted to try to keep as much of the configuration info as possible in the config file and not in my code. In order to use the ApplicationContext.DataPortalProxy or ApplicationContext.DataPortalProxyFactory settings it looks like I would need to make a custom proxy or custom proxy factory that would be hard coded to talk to each different endpoint. Another option here would be to have the client app talk directly to its local database after a "check out". This is something that we had considered doing, but we want to keep access to the database as protected as possible so having a client application with full read/write access to the database running under the context of whatever user is currently logged into Windows would not be ideal.

As far as I can tell, ApplicationContext.DataPortalUrlString is only used when the DataPortal defaults to using the WsHttpBinding. Since we're not using WsHttpBinding at all, that rules this option out.

What I ended up doing to get the behavior I was looking for was create a custom ChannelFactory. I had some code from a previous based on the example here: http://weblogs.asp.net/cibrax/archive/2007/10/19/loading-the-wcf-configuration-from-different-files-on-the-client-side.aspx that I modified to keep its own configuration cache.

I also added an event to my class that is responsible for writing the changes to the config file and had my custom ChannelFactory listen for that even so it would know when to update it's configuration cache then had the CreateDescription() override always read from that configuration cache.

I then made a custom proxy that inherits from the CSLA WcfProxy class. The only modification to this custom proxy was an override of GetChannelFactory() to return an instance of my custom ChannelFactory.

Copyright (c) Marimer LLC