Windows Vista Beta | WinVistaBeta.com - Message | Assigning behavior configuration dynamically using code

November 21, 2008  
Subject: Assigning behavior configuration dynamically using code
Group: microsoft.public.windows.developer.winfx.indigo
Date: 1/22/2008 6:41:46 PM
From: "Sherif ElMetainy" [Email Address Protection]

Greetings,

I am writing an application where I use ChannelFactory to create client
channels. I want to be able to choose one of the endpoint behaviors defined
in my config file. I didn't find any API to apply an endpoint behavior
configutation to my factory's service endpoint. I don't have any client
endpoints defined in the application config file. These are created
dynamically from code. I came up with a solution which seems to work (I
haven't extensively tested it yet) but I don't feel comfortable using it.
The code for my solution is below:

ChannelFactory<IMyContract> channelFactory = new
ChannelFactory<IMyContract>();
ApplyEndpointBehaviorConfiguration(behaviorConfigurationName,
channelFactory.Endpoint); /* this method implemention shown below*/

static void ApplyEndpointBehaviorConfiguration(string
behaviorConfigurationName, ServiceEndpoint serviceEndPoint) {
/* open application configuration */
Configuration config =
ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
/* get behaviors configuration section */
BehaviorsSection behaviorsSection =
ServiceModelSectionGroup.GetSectionGroup(config).Behaviors;
/* get endpoint behavior element from configuration */
EndpointBehaviorElement endpointBehaviorElement =
behaviorsSection.EndpointBehaviors[behaviorConfigurationName];
/* clear existing behaviors because ClientCredentials would cause errors
because it is already defined */
serviceEndPoint.Behaviors.Clear();
/* Get CreateBehavior method using reflection because it is a protected
internal virtual method */
MethodInfo createBehaviorMethodInfo =
typeof(BehaviorExtensionElement).GetMethod("CreateBehavior",
BindingFlags.Instance | BindingFlags.NonPublic);
foreach (BehaviorExtensionElement behaviorExtensionElement in
endpointBehaviorElement) {
/* Loop the behavior extensions and call CreateBehavior for each */
serviceEndPoint.Behaviors.Add((IEndpointBehavior)createBehaviorMethodInfo.Invoke(behaviorExtensionElement,
null));
}
}


The reasons I am not happy with this solution are
- Using reflection to access and call non public methods can cause problems
when running in non full trust scenarios (not a big deal in my case, but my
code is likely to be reused in other projects where this might be a problem)
- Most importantly, I am not using the CreateBehavior method they way it is
intended to be used since it is supposed to be called by the WCF runtime and
not from my code. I am worried about any undefined behavior or unexpected
hard to fix bugs this might cause.
- I feel I am shooting myself in the foot by using this unsupported solution
that might not work in future versions (CreateBehavior method is protected
virtual and not private though, so it would be a breaking change if it is
removed or changed in future versions)

I would greatly appreciate if someone can guide me to a cleaner and
supported way to do this.

Sorry for the long post, and thanks a lot in advance.

Best regards,
Sherif El-Metainy


Back