Something that pops up every once in a while on the Spring.Net user forum is how to change your connection string at runtime. You need this behaviour for instance when you have a multi tenant application.

Out of the box Spring.Net comes with two DbProviders to change information about your connection string at runtime. One provider to change the credentials at runtime named UserCredentialsDbProvider, and one that can choose a connectionstring from a predefined list called MultiDelegatingDbProvider.

If you want to change the connection string at runtime, for instance based on the current logged in user, what works best is to either subclass DelegatingDbProvider or UserCredentialsDbProvider (which actually is a subclass of DelegatingDbProvider).

Attached you can find a quick and dirty sample which shows what you need to hook up.

The ‘FixedPool’ mode is based on the SimplePool which you can find in the Spring.Pooling library. Meaning that at any given time there can be a maximum of x amount of channels. Where x equals the SimplePool’s size. So if the size of your pool is 5 and you request a 6th channel while the previous 5 are still busy doing their business you’ll get a blocking thread until one of the previous five is returned to the pool. This is good for when you want to limit the connectivity to your server, but don’t forget that it will block the calling thread when you request more channels than there are available.

The other pool mode is ‘VariablePool’. This is a pool that grows and shrinks depending on the load. So if you request 6 channels you’ll get 6 channels which will be available for future requests when returned to the pool. Channels which are no longer usable will be removed and new ones will be created when needed.

I spend most of the time trying to find a good away around my dependency on ChannelFactory. Since that class has a method ‘CreateChannel’ which takes no arguments and the factory can be configured using the endpoint name in your system.servicemodel section. The interface which the class implements doesn’t have this. The classes which populate a channelfactory from the app.config are marked internal and so you can’t use them.

The only solution I found that worked pretty ok was a wrapper interface which exposes the CreateChannel method, it helped me to test the code without a channelfactory instance.

I did a lot of renaming in the codebase but on the consuming end not much has changed.

If you want to use your own channel manager, you can use the ProductTemplate to hook everything up. The sample below illustrates this, here the variable pool is configured via the template instead of using the ChannelManagementMode property of the FactoryObject.

setting the pool size of a fixed sized pool via the FactoryObject, for now the default of 5 is used

extend or add a new pool based on the SimplePool. At the moment closed or faulted channels are not removed from that implementation, meaning that when your 5 channels are closed the pool will raise an exception.

Updated version is now available, no channel pooling yet but I changed the way default values and the ProductTemplate were being handled. I’ve already used the library successfully at work in a very heavy WCF application. I found some issues with it, like when you wanted to configure the ChannelFactory in your configuration file, but these are now fixed.

First drop available of the ChannelManagement library. Currently only support single action channels, meaning that after executing the operation the channel is closed. I hope to add pooling the coming week.

The zip contains the source code and an example project. Not much changes in the ‘end user’ code:

This is probably what you’ll need the most. You define the ChannelType, that is the interface exposed by the service you want to consume, and the EndpointConfigurationName, which is the name of the endpoint in the system.servicemodel section of your app/web.config. And that’s it. The behaviour of the channel in this case is that a new channel will be created for every operation you want to execute.

If you want channels to be reused, you can specify this by changing the value of the ‘ChannelManagementMode’. There are two predefined values you can use here, Recycle and ThrowAway. ThrowAway being the default. Not sure about these names though :-).

If one of the default ways to manage the lifecycle of a channel is not what you want or need you can create your own and specify it in the ProductTemplate property of the ChannelManagerFactoryObject. The example above shows how you can do this, in this case it would result in the same default behaviour you get in the first xml configuration I showed in the beginning of my post.

If you even want to customize the way a channel is retrieved, an action is executed on it and then handed back to the channel lifecycle manager, you can subclass ChannelActionWrapper and specify that type in the ChannelActionWrapperType property of the ChannelManagerFactoryObject. This is illustrated below: