Scott Seely

Sponsors

The Lounge

Wicked Cool Jobs

Syndication

News

  • INETA Community Champions
Custom ChannelFactory Creation

Just the other day, Derik Whitaker ran into some issues setting up his ChannelFactory to handle large object graphs being returned to his clients (post is here). After some back and forth through email, we came up with a solution. Instead of use the default ChannelFactory<T>, we created a new class that inherits from ChannelFactory<T> and sets the DataContractSerializerBehavior to handle int.MaxValue objects in the graph.

The trick is to override the ChannelFactory<T>.OnOpening method. This method is called as the ChannelFactory is opened and allows a derived class to alter the behavior at the last minute. All OperationDescriptions have a DataContractSerializerOperationBehavior attached to them. What we want to do is pull out that behavior and set the MaxItemsInObjectGraph property to int.MaxValue so that it allows all content to be serialized in. Derik’s use case was valid—he owned the client and server and wanted to incur any penalty associated with reading ALL data. If you are in a similar situation and need to remove that safety net/throttle in your code, here is what you need. Note that the constructors aren’t interesting other than they preserve the signatures made available through ChannelFactory<T> and make them visible in my DerikChannelFactory<T>.

 

public class DerikChannelFactory<T> : ChannelFactory<T>
{
    public DerikChannelFactory(Binding binding) : 
        base(binding) { }

    public DerikChannelFactory(ServiceEndpoint endpoint) : 
        base(endpoint) { }

    public DerikChannelFactory(string endpointConfigurationName) : 
        base(endpointConfigurationName) { }

    public DerikChannelFactory(Binding binding, EndpointAddress remoteAddress) : 
        base(binding, remoteAddress) { }

    public DerikChannelFactory(Binding binding, string remoteAddress) : 
        base(binding, remoteAddress) { }

    public DerikChannelFactory(string endpointConfigurationName, 
        EndpointAddress remoteAddress) : 
        base(endpointConfigurationName, remoteAddress) { }

    protected override void OnOpening()
    {
        foreach (var operation in Endpoint.Contract.Operations)
        {
            var behavior = 
                operation.Behaviors.
                    Find<DataContractSerializerOperationBehavior>();
            if (behavior != null)
            {
                behavior.MaxItemsInObjectGraph = int.MaxValue;
            }
        }
        base.OnOpening();
    }
}

 

The OnOpening override is also a good place to inject behaviors or other items if you want to make sure that all ChannelFactory instances have the same setup without resorting to configuration or code for each instance.


Posted 05-07-2010 5:06 PM by Scott Seely

[Advertisement]

Comments

Derik Whittaker wrote re: Custom ChannelFactory Creation
on 05-07-2010 8:12 PM

Scott,

Thanks again for the help.

Andy wrote re: Custom ChannelFactory Creation
on 05-13-2010 8:36 AM

Scott,

Nice. I had this exact same problem around 3 months ago.  By the time I discovered it (late on in the project) I was simply glad to get a solution (same as Derik's original as it happens) but it was gnawing away at me as to this not being ideal.

I like what you guys have done here believe me - I might take it to rework into my project, so thanks for that! Yet looking at your resolution I still have something gnawing away and I think I now know what it is....its just WCF!  

So far I've only worked on 2 projects using WCF so my experience here is limited, but I think my uneasy feeling simply comes from having to crank so my WCF configuration-type code.  ASMX web services gave me a better feeling for services that "just worked" for want of a better explanation, but with WCF it just seems that we are all back to coding things that should be a solved problem by now.  I think WCF is still suffering from trying to be a lot of things to a lot of people, and not fully managing it for anyone.  Is it just me?

Scott Seely wrote re: Custom ChannelFactory Creation
on 05-17-2010 8:00 PM

Andy- in general, things do just work. 4.0 makes things even better. In the 3.0 days, the team was trying to ship the right thing and not add too much "sugar" because the wrong kind of simplifications are more harm than good. In 4.0, the team had lots of implementation experience to be able to add the right ease of use things.

Also, you need to keep in mind that WCF is a messaging stack. You need sensible throttles so that you don't shoot yourself in the foot. The code is pretty simple to write and is much simpler than comparable code if you needed to own the entire networking stack.

Finally-- this code, overall, is as simple as ASMX. Isn't it? Something comparable in ASMX requires a lot more code. And no, I'm unwilling to write the comparable piece unless absolutely necessary ;)

Add a Comment

(required)  
(optional)
(required)  
Remember Me?

About The CodeBetter.Com Blog Network
CodeBetter.Com FAQ

Our Mission

Advertisers should contact Brendan

Subscribe
Google Reader or Homepage

del.icio.us CodeBetter.com Latest Items
Add to My Yahoo!
Subscribe with Bloglines
Subscribe in NewsGator Online
Subscribe with myFeedster
Add to My AOL
Furl CodeBetter.com Latest Items
Subscribe in Rojo

Member Projects
DimeCasts.Net - Derik Whittaker

Friends of Devlicio.us
Red-Gate Tools For SQL and .NET

NDepend

SlickEdit
 
SmartInspect .NET Logging
NGEDIT: ViEmu and Codekana
LiteAccounting.Com
DevExpress
Fixx
NHibernate Profiler
Unfuddle
Balsamiq Mockups
Scrumy
JetBrains - ReSharper
Umbraco <-- NEW Friend!
NServiceBus <-- NEW Friend!

 



Site Copyright © 2007 CodeBetter.Com
Content Copyright Individual Bloggers

 

Community Server (Commercial Edition)