Thursday, 21 February 2013

Proxy Object Generation for MVC and WebAPI Controllers

After working on my WebApi proxy object project, which I discussed in the previous post, I decided to make it more generic allowing it to also be used on MVC contollers.

I have posted a demo on Code Project for people to check out.

Liam

Friday, 11 January 2013

Automatic creation of WebAPI proxy object

It has been a while since my last blog post but, I feel my current project is worth sharing. So, basically I have an assignment which means I get to play about with WebAPI, and after a while I started thinking maybe a proxy object could come in handy, the sort that WCF uses, so instead of having to know the location of each WebAPI method and how to serialise the data, I could call a method on an object and let it do the hard work;

So the concept behind my idea is: (I started this about 6 hours ago so it might still need tweaking)

An ApiController no longer inherits the ApiController class but a ContractedApiController class which is a sub-class of ApiController but contains the method GetWebApiInfo. This method returns a WebApiInfo object.

The WebApiInfo class contains two lists one containing WebApiMethodInfo objects, the other containing WebApiClassDefinition objects. The class names a pretty much explain the classes, the WebApiMethodInfo class contains a method name, request type (get, post, ect.), return type, and a dictionary storing parameter names and types. The WebApiClassDefinition stores a class name along with a dictionary of property names and types.

When the GetWebApiInfo is called, it first searches for all methods that hold the custom attribute WebApiContractAttribute, then maps these methods onto WebApiMethodInfo objects, if any non-system objects (need to work on this) are found as parameters or return types they are mapped onto WebApiClassDefinition objects. Finally when all this is done the WebApiInfo object is returned as Json or XML.

To utilise this I created a T4 template that calls GetWebApiInfo and based on the metadata received, generates a WebAPI proxy object and data transfer objects locally. As you can see below intellisense is picking up the "Get" and "WebApiMethod", and the "TestClass" class has been generated.


I'll be back with any more developments I have.

Liam

Saturday, 28 January 2012

Asynchronous Method Wrapper

So I have finally created an asynchronous wrapper for my web service assignment, allowing any method to called asynchronously. I'll give a quick demo of how it work:

1.  The Method Call
A method from within an asynchronous wrapper class.
So, we start off with the wrapped method, in this case the GetUserAsync method is going to allow us to retrieve a specific user asynchronously. The method makes a call to DoAsync, inherited from the AsyncCalls class (which will be discussed later), passing the GetUser method (Converted into the right format, see number 2), the parameters it requires in an object array, and the name of the event.

 2. Converting the method format
The DoAsync method from the AsyncCalls class
The reason the GetUser need to be converted when being passed to DoAsync, is because it does not match the GenericAsyncDelegate signature.

The GenericAsyncDelegate signature for a method which takes an object[]  a string and returns an AsyncData object
So to convert GetUser (A method that takes an int and returns a WebUser object) into the right format, I call the ConvertFuncSingleArg method.

ConverFuncSingleArg method returning a method converted into a GenericAsyncDelegate.
As you can see the method returns an anonymous delegate in the form of a GenericAsyncDelegate, using ConvertResult to change the result of passed method into an object[], allowing it to be wrapped in a AsyncData object. Because the methods return type is unknown until runtime, problems are caused if a collection is passed. A simple example of this would be if the return type was List<Object>,  T would be assigned this type when the method is called, and all the checks will fail, as T is not an array and is not of type List<List<Object>>, so the method will return object[] {List<Object>}.

A method to convert the object passed into an object[]
To solve the above problem, the generic type passed must be the return type in a non-collective form. This can be done using reflection, so I created a method as a layer to do this.

The middle layer of converting the return type.

First of all, temp is set to the type of T, so if all tests fail, it is treated as the return type. Then I check if it is a type of array, if this is true then temp is set to the element type, otherwise treat it as a generic collection attempt to take it's generic type, if a generic type is found then set temp. In the above case Type.GetType will work as object is part of the referenced System namespace, but in cases where the type does not exist in a referenced namespace, the DLL needs to be loaded, and the type retrieved from it. Once the checks are complete the ConvertReturnType method needs to be called with temp as it's generic type, I use reflection to create the method, then invoke it with with MethodResult as a parameter.

3. The DoAsync Method
DoAsync method which sets up the process.
The method starts by defining the callback delegate, this is the method is used to process the result of the async call, in this case the method will be called GenericAsyncCompleteCallback. Secondly creates a AsyncOperation object with no state, which is used to track and report the progress of the operation. Finally Istart the method (notice BeginInvoke being used not Invoke, as Invoke is synchronous), we pass the two GenericAsyncDelegate parameters, a reference to the callback, and the AsyncOperation object.

4. The Callback
The callback method.
The callback method gets passed an object of IAsyncResult, which contains objects relating to the async call. I then extract the objects I want; the method doing the work and the state of the operation. I then create the GenericAsyncCompletedEventArgs object (an extension of the AsyncCompletedEventArgs class) containing the result of the async operation, which will be passed to the event handler. Finally we update the state of the AsyncOperation to completed, specifying the operation complete method (which will be called after this) and the event arguments.

5. Completed Call
The even called on completion.
The only job of the OnGenericAsyncCompleted method is to fire the event handler, once the operation is complete.
The delegate for the event handler, and the event to be handled.
6. The End
Now everything is complete I can show you the code in a working context.
A test situation
Thank you for reading, my next post is most likely to be based on my Lisp assignment, hopefully you will enjoy it.

Liam 



Wednesday, 25 January 2012

The Start

Just a bit of background information.

My name is Liam Russell, and am currently studying Computer Science at Teesside University.

Hopefully I will be posting regularly, about new programming challenges, and discoveries that I make.