gustavomick
gustavomick

Reputation: 115

C# - Castle WCF Facility - How to properly setup client side OperationBehavior + WcfEndpoint.FromEndpoint usage

I was playing with wcf facility and trying to setup DataContractResolver but I couldn't find any example...

In the end I make it work .. not sure this is ok though ..

Questions

  1. (code below) Is this the right way to accomplish behavior configuration or I am misunderstanding something?

  2. also .. I had to disable async to make it work.. is it a library bug/issue?

Others nice to have before research ..

  1. I was really thinking about performance impact of wcf facility interceptions.. vs benefits of use it. any thoughts?

  2. why is this library not updated any more, (http://docs.castleproject.org/Windsor.AllPages.aspx?Cat=Windsor.WCF-Facility) my concern is regarded using a library that is not longer under maintenance?


        var contractdesc = ContractDescription.GetContract(typeof(T));
        if (dcr != null)
        {
            foreach (var operation in contractdesc.Operations)
            {
                operation.Behaviors.Find<DataContractSerializerOperationBehavior>().DataContractResolver = dcr;                    
            }

        }

        var myEndpoint = WcfEndpoint.FromEndpoint(
            new System.ServiceModel.Description.ServiceEndpoint(
                contractdesc
                , binding, new EndpointAddress(Url)));

        var clientModel = new DefaultClientModel { Endpoint = myEndpoint };
        clientModel.WithoutAsyncCapability();

            container
                .Register(
                    Types
                        .From(typeof(T))
                        .InSameNamespaceAs<T>()
                        .If(m => m.IsInterface)
                        .Configure(
                            c => c.Named(c.Implementation.Name)
                                     .AsWcfClient(
                                     clientModel
                                     ).Interceptors(typeof(CastleServiceInterceptor))
                                ),
                        Component.For<CastleServiceInterceptor>()
                );

So i realized (debugging wcf facility) that if WantsAsyncCapability= true the DefaultClientModel is not copying all ServiceEndpoint behaviors, just endpoint behaviors (true is de fault configuration) so here ..

    public override ChannelFactory CreateChannelFactory(Type channelFactoryType, M clientModel, 
                                                        params object[] constructorArgs)
    {
        if (!clientModel.WantsAsyncCapability)
        {
            return base.CreateChannelFactory(channelFactoryType, clientModel, constructorArgs);
        }

        EnsureValidChannelFactoryType(channelFactoryType);

        ReplaceServiceEndpointAsyncContracts(constructorArgs);

        var interceptor = new CreateDescriptionInterceptor();
        var proxyOptions = new ProxyGenerationOptions(asyncChannelFactoryProxyHook);
        return (ChannelFactory)generator.CreateClassProxy(
            channelFactoryType, Type.EmptyTypes, proxyOptions, constructorArgs, interceptor);
    }

Then in ReplaceServiceEndpointAsyncContracts is recreating ServiceEndpoint

    private static void ReplaceServiceEndpointAsyncContracts(object[] constructorArgs)
    {
        for (int i = 0; i < constructorArgs.Length; ++i)
        {
            var endpoint = constructorArgs[i] as ServiceEndpoint;
            if (endpoint != null)
            {
                var asyncEndpoint = new ServiceEndpoint(ContractDescription.GetContract(
                    AsyncType.GetAsyncType(endpoint.Contract.ContractType)))
                {
                    Name = endpoint.Name,
                    Address = endpoint.Address,
                    Binding = endpoint.Binding,
                    ListenUri = endpoint.ListenUri,
                    ListenUriMode = endpoint.ListenUriMode
                };

                asyncEndpoint.Behaviors.Clear();
                foreach (var behavior in endpoint.Behaviors)
                {
                    asyncEndpoint.Behaviors.Add(behavior);
                }

                constructorArgs[i] = asyncEndpoint;
            }
        }
    }

Above can be seen that not contracto or operation behavior is copied.

So thats it, thanks.

Upvotes: 1

Views: 423

Answers (0)

Related Questions