WCF Extensibility

Post on 24-Feb-2016

86 views 0 download

Tags:

description

WCF Extensibility. Scott Reed Owner - Brain Hz Software scott@brainhzsoftware.com Instructor – DevelopMentor scottr@develop.com. WCF Design Goal. To be the single best way of getting any two pieces of software to communicate under any circumstances (assuming at least one is .NET). - PowerPoint PPT Presentation

transcript

WCF Extensibility

Scott ReedOwner - Brain Hz Software

scott@brainhzsoftware.comInstructor – DevelopMentor

scottr@develop.com

WCF Design Goal

• To be the single best way of getting any two pieces of software to communicate under any circumstances (assuming at least one is .NET)

Extensibility in a nutshell

• WCF doesn’t support everything out of the box

• When a limitation is reached WCF can still be used by adding or replacing a specific piece of the framework

• (Almost) everything can be extended• Infinitely flexible = more difficult than it needs

to be

BC A

BC A

B CA

B CA

B CA

Client Service

Service

Client Runtime

Channel

Channel

TransportChannel

byte[]

DispatcherRuntime

Client Codeparameters

Encoder

Service Typeparameters

Channel

Channel

TransportChannel

byte[]

Encoder

Service Model Layer

Channel Layer

ServiceHost

ChannelDispatcher

EndpointDispatcher

DispatchRuntime

DispatchOperation

ChannelStack

IChannel (Protocol)

IChannel (Protocol)

IChannel (Transport)

Behavior extensibility steps

1) Implement the functionality– MessageInspector, ErrorHandler, InstanceProvider, etc.

2) Hook up the functionality through behavior– ServiceBehavior, EndpointBehavior, OperationBehavior

3) Let WCF know about the behavior from #2– Programmatically, configuratively, declaratively

When Behaviors Run

1. Reflect Over T

2. Load Config

.Description

.Open();

ServiceHost() or ChannelFactory()

3. Build Runtime

4. Open Resources

Behaviors

[MyBehavior]

<myBehavior />

.Description.Behaviors.Add(new MyBehavior());

Three Behaviors

• All three behavior types have the same methods:

public void AddBindingParameters(<description>, BindingParameterCollection);

public void ApplyClientBehavior(<description>, <client plumbing>);*

public void ApplyDispatchBehavior(<description>, <service plumbing>);

public void Validate(<description>);

* ApplyClientBehavior isn’t present in IServiceBahvior

ParameterInspectors

public interface IParameterInspector{ object BeforeCall(string operationName, object[] inputs); void AfterCall(string operationName, object[] outputs, object returnValue, object correlationState);}

Parameter InspectionUseful for consistent client and service side validation

Client Operation Client Runtime Channel

public interface IClientMessageFormatter{ Message SerializeRequest(MessageVersion messageVersion, object[] parameters); object DeserializeReply(Message message, object[] parameters);}

Message FormattingActually creates the message from parameters, and breaks apart the message into parameters and return value.

Formatter

Client Operation Client Runtime Channel

public interface IClientMessageInspector{ object BeforeSendRequest(ref Message request, IClientChannel channel); void AfterReceiveReply(ref Message reply, object state);}

Message InspectionThe most useful, allows last minute manipulation of the message before being sent into the channel layer.

MessageInspectors

Client Operation Client Runtime Channel

Other client side extension points

• Via (sends to intermediaries)• ChannelInitializers (manipulate channel stack)

• But the service has far more extensibility…

Demo

• Client side message inspector• Adding a behavior extension element

Error Handling

DispatchOperationDispatchRuntimeEndpointDispatcherChannelDispatcher

public interface IErrorHandler{ bool HandleError(Exception error); void ProvideFault(Exception error, MessageVersion version, ref Message fault);}

Error Handlers

Allows a central place to perform exception to fault message translation.

Address / Contract Filtering

DispatchOperationDispatchRuntimeEndpointDispatcherChannelDispatcher

public abstract class MessageFilter{ IMessageFilterTable<FilterData> CreateFilterTable<FilterData>(); bool Match(Message message);}

AddressFilter

ContractFilter

Allows the messages to be matched to an appropriate dispatch runtime.

Providing InstanceContext

DispatchOperationDispatchRuntimeEndpointDispatcherChannelDispatcher

public interface IInstanceContextProvider{ InstanceContext GetExistingInstanceContext(Message message, IContextChannel channel); void InitializeInstanceContext(InstanceContext instanceContext, Message message, IContextChannel channel); bool IsIdle(InstanceContext instanceContext); void NotifyIdle(InstanceContextIdleCallback callback, InstanceContext instanceContext);}

InstanceContextProvider

Allows special case instancing modes

Providing Instance

DispatchOperationDispatchRuntimeEndpointDispatcherChannelDispatcher

public interface IInstanceProvider{ object GetInstance(InstanceContext instanceContext,Message message); void ReleaseInstance(InstanceContext instanceContext,object instance);}

InstanceProvider

Allows service object pooling

Message Inspection (again)

DispatchOperationDispatchRuntimeEndpointDispatcherChannelDispatcher

public interface IDispatchMessageInspector{ object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext); void BeforeSendReply(ref Message reply, object correlationState);}

MessageInspectors

The most useful, allows manipulation of the message right after being received from the channel layer.

Operation Selection

DispatchOperationDispatchRuntimeEndpointDispatcherChannelDispatcher

public interface IDispatchOperationSelector{ string SelectOperation(ref Message message);}public SynchronizedKeyedCollection<string, DispatchOperation> Operations { get { } }

OperationSelector

Allows operation selection by something other than Action

Message Formatting (again)

DispatchOperationDispatchRuntimeEndpointDispatcherChannelDispatcher

public interface IDispatchMessageFormatter{ void DeserializeRequest(Message message, object[] parameters); Message SerializeReply(MessageVersion messageVersion, object[] parameters, object result);}

Formatter

Actually creates the message from parameters, and breaks apart the message into parameters and return value.

Operation Invocation

DispatchOperationDispatchRuntimeEndpointDispatcherChannelDispatcher

public interface IOperationInvoker{ object[] AllocateInputs(); object Invoke(object instance, object[] inputs, out object[] outs); IAsyncResult InvokeBegin(object instance, object[] inputs, ...); object InvokeEnd(object instance, out object[] outputs, ...);}

Invoker

Actually takes control of calling the service object.

Parameter Inspection (again)

DispatchOperationDispatchRuntimeEndpointDispatcherChannelDispatcher

public interface IParameterInspector{ object BeforeCall(string operationName, object[] inputs); void AfterCall(string operationName, object[] outputs, object returnValue, object correlationState);}

ParameterInspectors

Useful for consistent client and service side validation.

Other service extensibility points• Extensions• ChannelInitializers• ServiceThrottle• ExternalAuthorizationPolicies• RoleProvider• ServiceAuthorizationManager• InputSessionShutdownHandlers• InstanceContextInitializers• FaultContractInfos• CallContextInitializers• Etc...

Demo

• Service side error handler

Channel Layer extensibility

• Easy ways:– Binding configuration– Programmatic binding manipulation– Custom bindings

• Hard way– Writing a protocol channel

• Really hard way– Writing a transport channel

Writing a Channel (Overview)

• To write a channel, you must– Write the channel itself

• Support the proper “shapes”– Input, Output, Duplex, Request, Reply, RequestContext

• Possibly provide asynchronous versions of all method– Write a ChannelFactory– Write a ChannelListener– Write a BindingElement

Extensibility Summary

• If possible stick with Service Model layer– There are tons of extension points– It’s not that hard to do

• If you have to write a channel– Plan on spending a couple of weeks