Dynamic configuration of WcfDataPortal

Dynamic configuration of WcfDataPortal

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


dlutz52 posted on Thursday, June 14, 2007

Hello all!

Is there any method (outside of modifying CSLA code or having multiple builds) to make the value of the WcfDataPortal endpoint info be based upon where the code is executing? Let me explain.

In the place where I work we are proceeding with building a new case management system for one our departments using CSLA 3.0 and WCF.

We have three environments - dev, test and stage. Each of these environments are 3-tier and mirrors of each other as far as app and database servers are concerned. Each of these three environments have their own distinct WcfDataPortal, so each have a different endpoint for the channel based on what environment the app is executing in.

In the WcfProxy.vb file, CSLA gets the endpoint info from the app.config file using a constant named _endpoint set to 'WcfDataPortal' (the name of the endpoint in the app.config file.) This value gets passed to the ChannelFactory constructor which proceeds to read the endpoint info from the config file.

Now to what I am really getting at. Since this value is stored in app.config, to have the same app run in the three enviroments, we would have to have three app.config files - either three seperate builds or one build and three different copies of of app.exe.config file. We would like to avoid both of these alternatives.

The most ideal solution would be to have a single app.config with multiple endpoints identified by a different value for the name attribute and be able to dynamically trigger the app to use one or the other based on the 'name' of the endpoint.

For this to work, there would need to be a static method to set the _endpoint variable to the desired value (having it fall back to 'WcfDataPortal' as a default value.) This would be similar setting the default format string on the SmartDate class using the SetDefaultFormatString method.

Would such a thing be possible/desireable in the public CSLA codebase? Or should I just bite the bullet and make the necessary code changes to the CSLA code we are using here?

Is there any alternative which I may be clueless about?

A very similar concept is presented here by Andre.

Best regards --
David Lutz

RockfordLhotka replied on Friday, June 15, 2007

The obvious alternative is to create your own proxy class that does what you want. Remember that the data portal uses a provider model to load the client-side proxy, so you can always create your own proxy and use that instead.

I could make the endpoint value configurable, but I'm not entirely sure I see the value. I'd have to make it configurable through the app.config file again, as there's no other known/reliable place to set this value.

Or I suppose I could make it a static/Shared property of WcfProxy so you could set it through code, though it isn't clear to me how that'd work, because you'd still have to detect some config value to know what environment you are in?

Or, and I think I like this best, I could make a protected EndPoint property within WcfProxy. That would allow you to subclass WcfProxy to create your own custom proxy that could set that value however you see fit - and the default would be the current behavior. But if you want to do something else, you could easily create the subclass and have the data portal load your custom proxy instead of the standard one.

dlutz52 replied on Wednesday, June 20, 2007

Rocky --

Thanks for your consideration of this issue. Sorry about delayed response but I was away from the computer for a couple of days and then I needed to digest your response for a day.

First & fourth paragraph: I understand what you are talking about here, but I would rather be writing my code for my application and using CSLA out-of-the-box.

Second paragraph: I could envision a situation where I had an endpoint named WcfDataPortal and another named WcfDataPortalBackup in the <system.serviceModel><client> section of the app.config. If one got an exception trying to reach WcfDataPortal then one could try to use WcfDataPortalBackup as an alternative and keep on working. Web services are easy to deploy and will become widespread over time. Another use case could be that an organization has a central web service for user authentication and a seperate web service for the application.

Your third paragraph points to my interest here. We have three seperate environments - dev, test,and production (including training would be a fourth) in which the developers (or even the app itself) will need to be able to switch between without having to change the app.config file to be different for each environment. Yes, detecting the environment is application specific and not anything that you would need to concern yourself with. To be able to set the _endpoint variable to something other than the default WcfDataPortal would allow one to do this since it is the endpoint's name in the app.config that gets passed to the ChannelFactory(Of IWcfPortal) constructor. Correct?

I still like my idea of being able to set then value of the endpoint name being sent to the ChanelFactory constructor in a way very similar to how CSLA handles the format string for a SmartDate - simple and flexible within a strict set of requirements (being able to access multiple web services in a single application with CSLA out-of-the-box) using a static method to set the current value of the endpoint name.

Of course I will defer to your broader vision of CSLA and work with any decision you should make about this.

Best regards --
David Lutz

RockfordLhotka replied on Wednesday, June 20, 2007

dlutz52:

To be able to set the _endpoint variable to something other than the default WcfDataPortal would allow one to do this since it is the endpoint's name in the app.config that gets passed to the ChannelFactory(Of IWcfPortal) constructor. Correct?

Yes, ultimately it is either this, or create a complete custom channel, which seems like a lot of work to solve a simple problem.

The two options for doing this are to

  1. Put a static/Shared EndPoint propery on WcfProxy
  2. Put a protected EndPoint property on WcfProxy

The only difference between these two is where you write your code to detect the environment and set the EndPoint property value.

In option 1, you'd have to find a place early in your application's lifecycle to run your detection code, such that it would run before any other code. This location is different for Windows, WPF and web apps, and would lead to a broadly non-standard approach to solving the issue.

In option 2, you'd have a well-defined place to put this code: a subclass of WcfProxy that did nothing more than implement a constructor to set the EndPoint property. This code would automatically be called before the WcfProxy was used, so there'd be no ambiguity or inconsistency about how or where to put the code to make it work.

Option 2 results in code like

Public Class WcfProxy
  Inherits Csla.DataPortalClient.WcfProxy

  Public Sub New()
    Dim endPoint As String
    ' find endpoint value from somewhere
    Me.EndPoint = endPoint
  End Sub

End Class

The bolded line of code is where your magic must happen.

This makes a great deal of sense to me as an extensibilty point, so I'll roll it into Beta 2.

dlutz52 replied on Wednesday, June 20, 2007

Rocky --

Thanks! I am a happy camper now. Big Smile [:D]

BTW, any ETA on Beta 2?

David

RockfordLhotka replied on Wednesday, June 20, 2007

My plan is this weekend (earlier if I’m lucky).

 

The only thing I need to wrap up is to get the CanExecute() functionality implemented in the C# version and I’m ready to go. Unfortunately this week has been very busy with other things and I’ve had little time to spend on CSLA development.

 

Rocky

 

 

From: dlutz52 [mailto:cslanet@lhotka.net]
Sent: Wednesday, June 20, 2007 4:13 PM
To: rocky@lhotka.net
Subject: Re: [CSLA .NET] Dynamic configuration of WcfDataPortal

 

Rocky --

Thanks! I am a happy camper now. Big Smile <img src=">

BTW, any ETA on Beta 2?

David



Copyright (c) Marimer LLC