I'm trying to build a small message/event system where messages may be requests.
Request handlers implement the IHandlerOf<T> interface like
public class UserService : IHandlerOf<ISearchRequest>
{
private void ProccessRequest(ISearchRequest request)
{
}
}
I'm unsure of how I should handle replies since multiple handlers can "answer" a request. How would you design the reply part? Build a list of replies in the message broker, or include the reply object in the process method and let all handlers work against the same reply object?
Examples would be appreciated.
Or do you have any links to existing solutions? Using service buses (like nservicebus) seems a bit overkill since everything is in-process.
Update
My current solution (Work in progress). The broker creates the response object by inspecting the IHandlerOf<> interface which is registered for the request type being used in BeginRequest.
The down side with the solution is that nothing ties the request and reply together which would give no compile errors if a incorrect reply type is mapped to a request type. Although the broker would thrown an error during the registration process if a request got two different response types.
The broker uses try/catch around each handler invocation to be able to continue process the request handlers even if one of those throws an exception. I haven't really decided what to do with the exceptions yet. One handler might throw while another one successfully handled the request.
The handler interface:
// interface defining a class which would handle a request
public interface IHandlerOf<TRequest, TResponse>
where TRequest : IRequest
where TResponse : IResponse
{
void ProcessRequest(IRequestContext<TRequest, TResponse> context);
}
Example implementation
public class FindContactsRequest : IRequest
{
public string SearchValue { get; set; }
}
public class FindContactsResponse : IResponse
{
public ICollection<string> Contacts { get; set; }
}
public class UserService : IHandlerOf<FindContactsRequest, FindContactsResponse>
{
public void ProcessRequest(IRequestContext<FindContactsRequest, FindContactsResponse> context)
{
if (context.Request.SearchValue == "blabla")
{
context.Response.Contacts.Add("My contact name");
}
}
}
broker interface
public interface IMessageBroker
{
IAsyncResult BeginRequest(IRequest request, AsyncCallback callback, object state);
IResponse EndRequest<T>(IAsyncResult result) where T : IResponse;
}
Sample usage
var ar = _broker.BeginRequest(new FindContactsRequest("blabla"));
var response = _broker.EndRequest<FindContactsResponse>(ar);
Console.WriteLine("Woho, found " + response.Contacts.Count + " contacts.");
If all of the handlers work against the same reply object, then the reply object needs some kind of logic to prevent a bad handler from destroying the replies from other handlers. That is, if the reply object contained a List<string>, for example, a misbehaving handler could call Clear on the list and all would be lost. So the reply object would need to wrap that list (by providing an AddReply method or some such) to prevent such behavior.
Also, if all of the handlers work against the same reply object, then multithreaded request handling becomes more difficult. The reply object has to handle thread synchronization to prevent data corruption.
If, on the other hand, the message broker handles combining the replies, you're much more flexible. It can call each handler in turn (sequentially), or it can use asynchronous calls to run multiple handlers in parallel. It seems like the message broker would be the easier and more flexible place to put the logic for combining replies.
Related
Is there a way in WCF to check some logic based on the type of Request it receives? Can this be done in the actual service endpoint code?
For example:
After Service Initialization my service receives a PUT Request. In myService.svc.cs I would like to have logic that looks like this:
if httpRequest.Type == PUT
{
//Do Something
}
Is this possible? I'm sure there is a better way to handle requests than adding logic for every Operation Contract that is of type PUT. Apologies if this question doesn't make sense I'm sort of new to WCF and am trying to learn. Please let me know if you need clarifiers.
EDIT:
This is what myService.svc.cs looks like currently:
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode = ConcurrencyMode.Multiple)]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public partial class MyService: IMyService
{
public async Task<someObject> GetMethod1 () // Some GET Method
{
doSomethingForGetRequests();
//method implementation
}
public async Task<someObject> GetMethod2 () // Some GET Method
{
doSomethingForGetRequests();
//method implementation
}
public async Task<someObject> PutMethod1 () // Some PUTMethod
{
doSomethingForPutRequests();
//method implementation
}
doSomethingForPutRequests()
{
if(config.IsReadOnly)
{
throw new WebFaultException(HttpStatusCode.BadRequest);
}
}
}
I am wondering if there is a place where i can place doSomethingForGetRequest() and doSomethingForPutRequest() in a central location before the request reaches these methods so I don't have to add these methods to each one of my Service Methods.
Would global.asax.cs Application_BeginRequest() be an appropriate place for this logic?
Maybe a message inspector can help you, it's called on every request that arrives at the service.
IDispatchMessageInspector defines the methods that enable custom inspection or modification of inbound and outbound application messages in service applications.
You can check out these posts:
Detect if action is a POST or GET method
Call the method automatically for each and every request in the WCF REST
Imagine you have a client and a server communicating via some kind of a message bus, which has this interface:
interface IBus {
void Send(Message m);
void Receive(Message m);
}
with Message being some POCO like this:
class Message {
public Guid Id {get;set;}
public string Data {get;set;}
}
So you can send a message via Send and when the response arrives the messaging infrastructure is going to invoke Receive method which essentially is just a callback. What I would like to do now is to write a method which will allow me to wait for response
Message WaitForResponse(Message request);
and use it like this:
var response = WaitForResponse(request);
Console.Write(response.Data);
I tried using TaskCompletionSource for it and it works great, but it requires async\await and I already got a lot of code written in this sync style. This code is now using ManulResetEventSlim objects stored in ConcurrentDictionary for synchronization, but it encounters performance issues when the number of requests waiting for response grow to a couple of hundreds (I assume because all threads are blocked with manualResetEventSlim.Wait()). I guess there should be a better way to do it which will require changes only to the implementation of WaitForResponse and will keep all method signatures untouched
Our application calls external services like
//in client factory
FooServiceClient client = new FooServiceClient(binding, endpointAddress);
//in application code
client.BarMethod(); //or other methods
Is it possible to track all of these calls (e.g by events or something like that) so that the application can collect the statistics like number of call, response time, etc? Note that my application itself needs to access the values, not only to write to a log file.
What I can think is to create a subclass of VisualStudio-generated FooServiceClient and then add codes like this
override void BarMethod()
{
RaiseStart("BarMethod");
base.BarMethod();
RaiseEnd("BarMethod);
}
and the RaiseStart and RaiseEnd method will raise events that will be listened by my code.
But this seems tedious (because there are a lot of methods to override) and there is a lot of repeated codes, my code needs to change everytime the service contract changes, etc. Is there a simpler way to achieve this, for example by using reflection to create the subclass or by tapping into a built-in method in WCF, if any?
The first thing I would look at is to see if the counters available in your server's Performance Monitor can provide you with the kind of feedback you need. There's built in counters for a variety of metrics for ServiceModel Endpoints, Operations and Services. Here is some more info http://msdn.microsoft.com/en-us/library/ms735098.aspx
You could try building an implementation of IClientMessageInspector, which has a method to be called before the request is sent and when the reply is received. You can inspect the message, make logs etc in these methods.
You provide an implementation of IEndpointBehavior which applies your message inspector, and then add the endpoint behavior to your proxy client instance.
client.Endpoint.Behaviors.Add(new MyEndpointBehavior())
Check out the docs for MessageInspectors and EndpointBehaviors, there are many different ways of applying them (attributes, code, endpoint xml config), I can't remember of the top of my head which apply to which, as there also IServiceBehavior and IContractBehavior. I do know for sure that the endpoint behaviors can be added to the client proxy collection though.
I found a simple way to do it by using dynamic proxy, for example Castle's Dynamic Proxy.
Firstly, use a factory method to generate your client object
IFooClient GetClient()
{
FooClient client = new FooClient(); //or new FooClient(binding, endpointAddress); if you want
ProxyGenerator pg = new ProxyGenerator();
return pg.CreateInterfaceProxyWithTarget<IFoo>(client, new WcfCallInterceptor());
}
And define the interceptor
internal class WcfCallInterceptor : IInterceptor
{
public void Intercept(IInvocation invocation)
{
try
{
RaiseStart(invocation.Method.Name);
invocation.Proceed();
}
finally
{
RaiseEnd(invocation.Method.Name);
}
}
//you can define your implementation for RaiseStart and RaiseEnd
}
I can also change the intercept method as I wish, for example I can add a catch block to call a different handler in case the method throw exception, etc.
I have a WCF threading question that I haven't been able to find a good answer on. I have an implementation of IDispatchMessageInspector that has the following AfterReceiveRequest implementation:
public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext)
{
return new SessionScope();
}
The constructor for SessionScope registers the current scope with a dictionary that basically tracks it by its thread. Then I have the following operation:
[MyServiceBehavior]
public class Service1 : IService1
{
public string GetData(int value)
{
// Uses SessionScope.Current object for various things
}
}
Will GetData be guaranteed to run on the same thread as the message inspector that inspected the WCF message previously? Likewise, would BeforeSendReply also be run on that same thread?
You can't guarantee that the request will remain on the same thread. IIS can (and will) pass it around between threads.
To achieve what you're going for you can load your object into the OperationContext.Current (or HttpContext.Current if you have aspCompatibilityMode turned on). I've done it by adding objects to the OperationContext.Extensions list:
First, your class has to implement IExtension
public sealed class SessionScope : IExtension<OperationContext> {
// your class details here
}
You would then need to add your object to the OperationContext:
public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext)
{
SessionScope scope = new SessionScope();
OperationContext.Current.Extensions.Add( scope );
}
After that it will be available to you everywhere regardless of thread switching.
Assuming that you are running under IIS the answer is no.
IIS has a thing called "thread agility", which means that a single request can jump threads. We have several problems with this, in one case we got around this problem by using the http context.
Have a look at the answers to this question: Will a request in IIS run on a single thread?
I have a situation in a project I am currently working on at work that has left my mind restless the entire weekend. First, I need to explain my scenario, and the possible solutions I have considered.
I am writing a composite WCF service that will be aggregating a large amount of external API's . These API's are arbitrary and their existence is all that is needed for this explanation.
These services can be added and removed throughout the period of development. My WCF service should be able to consume the services using several methods (REST,SOAP,etc). For this example, I am focusing on communicating with the external APIS by manually creating the requests in code.
For example, we might have two API's ServiceX and ServiceY.
ServiceX is consumed by POST ing a web request with the data in the request body specifically.
ServiceY is consumed by POST ing a web request with the data appended to the URL(Yes...I know this should be a GET, but I didn't write the external API, so don't lecture me about it.)
In order to avoid redundant, duplicate code, I have wrapped the web requests using the command pattern, and am using a factory to build the requests.
For ServiceX, the data needs to be encoded and put into the request body, as oppose to ServiceY where the data needs to be iterated over and placed on the Post string.
I have a class structure like the following:
public abstract class PostCommandFactory
{
public ICommand CreateCommand();
}
public class UrlPostCommandFactory:PostCommandFactory
{
public ICommand CreateCommand()
{
//Initialize Command Object Here
}
}
public class BodyPostCommandFactory:PostCommandFactory
{
public ICommand CreateCommand()
{
//Initialize Command Object Here
}
}
public interface ICommand
{
string Invoke();
}
public class UrlPostCommand:ICommand
{
public string Invoke()
{
//Make URL Post Request
}
}
public class BodyPostCommand:ICommand
{
public string Invoke()
{
//Make Request Body Post Request
}
}
This allows me to cleanly separate the way that I am binding data to the request when they need to be send out, and essentially, I can also add additional classes to handle GET requests. I am not sure if this is a good use of these patterns. I am thinking an alternative might be using the Strategy pattern and specifying strategy objects for the different Request methods I might need to use. Such as the following:
public class RequestBodyPostStrategy:IPostStrategy
{
public string Invoke()
{
//Make Request Body POST here
}
}
public class UrlPostStrategy:IPostStrategy
{
public string Invoke()
{
//Make URL POST here
}
}
public interface IPostStrategy
{
string Invoke();
}
public class PostContext
{
pubic List<IPostStrategy> _strategies;
public IPostStrategy _strategy;
public PostContext()
{
_strategies = new List<IPostStrategy>();
}
public void AddStrategy(IPostStrategy strategy)
{
_strategies.Add(strategy);
}
public void SetStrategy(IPostStrategy strategy)
{
_strategy = strategy;
}
public void Execute()
{
_strategy.Invoke();
}
}
I am starting to think the Strategy pattern may be the cleaner solution.
Any thoughts?
I would use both.
Command is best practice for encapsulating requests and hiding implementation details. You should probably use it even if you only have one kind of request, as it promotes cleaner code. Essentially it's good practice to consider "what is the absolute minimum the rest of my code needs to know about how requests are executed and handled", which will lead you to the Command pattern.
Strategy is basically configuring your system at runtime with a general, consitent way to handle some ascpect of the operation, in this case generating the requests. This is also a good practice for testing, as you can substitute a test implementation of your strategy/request factory to fake actual connections etc.
Based on the examples for Command and Strategy that you have given, the Command pattern example looks exactly like a Strategy which I guess lead you to Strategy. I would also go with Strategy but would like to add that there's more to Command pattern than what you have included in the example. You should ask yourself questions like:
Do these Commands need to be stored and should be executed later point in time?
Is there a Invoker that needs to invoke these commands without caring about Command internals?
Would you want to have functionality of grouping different Commands together and executing them?
If this is the case then you should choose Command Pattern.