|
I was intrigued by this forum discussion about attaching context to the lifetime of a service operation.
http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=733385&SiteID=1
Basically, the question is how to create the equivalent of the HttpContext we have with ASP.NET requests. The OperationContext is the closest we have to a request lifecycle, and it turns out you can add to the context by implementing IExtension<OperationContext>.
Attached is a sample: CustomContext.zip (91.4 KB)
Here's how it works:
- I use a custom attribute at the service, that implements IServiceBehavior.
[ApplicationRequestContext] public class HelloIndigoService : IHelloIndigoService
- In IServiceBehavior.ApplyDispatchBehavior() I add a custom message inspector to the MessageInspectors collection for each endpoint. This makes it possible to intercept at the point messages are received, and just before reply messages are sent. In my example, the ApplicationRequestContextAttribue also implements IMessageInspector.
public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase) { foreach (ChannelDispatcher channelDispatcher in serviceHostBase.ChannelDispatchers) { foreach (EndpointDispatcher endpointDispatcher in channelDispatcher.Endpoints) { endpointDispatcher.DispatchRuntime.MessageInspectors.Add(this); } } }
- In IMessageInspector.AfterReceiveRequest() I add an instance of my ApplicationRequestContext to the OperationContext, like this:
OperationContext.Current.Extensions.Add(new ApplicationRequestContext());
- In IMessageInspector.BeforeSendReply() I remove the instance of ApplicationRequestContext from the OperationContext. In my opinion, this step should not be necessary, but without it you will not have a chance to clean up what you created in the ApplicationRequestContext to speed up garbage collection.
OperationContext.Current.Extensions.Remove(ApplicationRequestContext.Current);
- The IExtension<OperationContext> implementation has an Attach() and Detach() implementation. In Attach() you intitialize your context. In Detach(), cleanup.
- Anywhere else in the application when you want access to the context, you get it from the OperationContext.Current. I provide a static member in the custom context to get this information:
public static ApplicationRequestContext Current { get {return OperationContext.Current.Extensions.Find<ApplicationRequestContext>();} }
Many thanks to Scott Mason on the WCF team for helping me find the right hooks for this purpose...
|