Friday, August 24, 2012

Web API in ASP.NET MVC4

In the new version of ASP.NET, Microsoft has introduced some framework extension that has exciting possibilities.  Google, FaceBook, and the like have been exposing web API in some fashion for a while now, but it has always seemed limited to certain platforms.  It appears at a glance that we will be able to provide the same functionality with native ASP.NET and MVC4 applications.  This basically allows you to expose web service over straight up HTTP instead of traditional service hosting/messaging.

The gain is that you can create web-based integration points by leveraging  a native ASP.NET architecture at the same time.  This allows you to provide a user-story-based integration routine (ala FaceBook, Twitter) as a wrapper of /or in addition to any service layer integrations that may be exposed.  

Here are some points I read from Scott Gu's Blog on the topic.  He outlines the highlights and additions to the framework.  I think the real excitement is in the realization of the walls that are coming down on platform dependence and ease of developing rich client experiences with web services in a Windows environment.

Our new ASP.NET Web API support enables you to easily create powerful Web APIs that can be accessed from a broad range of clients (ranging from browsers using JavaScript, to native apps on any mobile/client platform).  It provides the following support:
  • Modern HTTP programming model: Directly access and manipulate HTTP requests and responses in your Web APIs using a clean, strongly typed HTTP object model.  In addition to supporting this HTTP programming model on the server, we also support the same programming model on the client with the new HttpClient API that can be used to call Web APIs from any .NET application.
  • Content negotiation: Web API has built-in support for content negotiation – which enables the client and server to work together to determine the right format for data being returned from an API.  We provide default support for JSON, XML and Form URL-encoded formats, and you can extend this support by adding your own formatters, or even replace the default content negotiation strategy with one of your own.
  • Query composition: Web API enables you to easily support querying via the OData URL conventions.  When you return a type of IQueryable<T> from your Web API, the framework will automatically provide OData query support over it – making it easy to implement paging and sorting.
  • Model binding and validation: Model binders provide an easy way to extract data from various parts of an HTTP request and convert those message parts into .NET objects which can be used by Web API actions.  Web API supports the same model binding and validation infrastructure that ASP.NET MVC supports today.
  • Routes: Web APIs support the full set of routing capabilities supported within ASP.NET MVC and ASP.NET today, including route parameters and constraints. Web API also provides smart conventions by default, enabling you to easily create classes that implement Web APIs without having to apply attributes to your classes or methods.  Web API configuration is accomplished solely through code – leaving your config files clean.
  • Filters: Web APIs enables you to easily use and create filters (for example: [authorization]) that enable you to encapsulate and apply cross-cutting behavior.
  • Improved testability: Rather than setting HTTP details in static context objects, Web API actions can now work with instances of HttpRequestMessage and HttpResponseMessage – two new HTTP objects that (among other things) make testing much easier. As an example, you can unit test your Web APIs without having to use a Mocking framework.
  • IoC Support: Web API supports the service locator pattern implemented by ASP.NET MVC, which enables you to resolve dependencies for many different facilities.  You can easily integrate this with an IoC container or dependency injection framework to enable clean resolution of dependencies.
  • Flexible Hosting: Web APIs can be hosted within any type of ASP.NET application (including both ASP.NET MVC and ASP.NET Web Forms based applications).  We’ve also designed the Web API support so that you can also optionally host/expose them within your own process if you don’t want to use ASP.NET/IIS to do so.  This gives you maximum flexibility in how and where you use it.

Friday, August 17, 2012

.NET Framework 4.5

I've been doing some reading on what's new with the .NET 4.5 framework.  It looks like there are plenty of items to dive into with details in the near future.  I found this poster on a blog outlining some of the items at a very high level.


I am going to dig in deeper on some of these C# 5.0 and WCF changes to see if there are some things worth carrying over into standards and practices.  If there is anything on this poster that you would like to see a deep-dive on, leave a comment or let me know via the contact page and I will try to put something specific together.

Monday, August 13, 2012

Multi-tenant WCF Services

Hosting a multi-tenant application using WCF
While doing some long-term architecture design, the task was given to work through a cloud-based application.  Our business requirements have resulted in the need for a multi-tenant application built on WCF services that can share physical instances for multiple tenants. The first thing that jumps out in this framework for me is that these services must not contain state level variables that would directly relate to any single tenant. In this model, for instance, a BLL type service should not contain a static list of 'droplist' items to be consumed by the software unless the listing was tenant/customer agnostic. This breakdown gives us the ability to scale at any point in the SOA, based on load or any other need that may present itself. The gain is that you are not locked into a 1:1 tenant:service instance relationship which allows for more host cost effective scaling. In our model, based on the type of data stored, we have decided to go with a separate catalog for each tenant. This point works for our model and while I know there are other models that work effectively, this is really not the target of the current post.

Building the flow and responsibilities 
The first obstacle presented was how to point a tenant at the corresponding catalog without having the SOA be inherently aware of the tenant. For our model, we have the user authenticating against a centralized database and service purposed exclusively for housing tenant information. This enables us to assume that a client will be self-aware and could be provided with their tenant information to some degree prior to engaging the full SOA of the application. The idea being that if we can have the service dynamically recognize the tenant based on the tenant self-identifying at the time of messaging, we can achieve a loosely coupled environment for services to perform with a disregard for the actual tenant entity.

Communicating tenant information
While thinking through a means to provide tenant information to the services, there are a couple of possibilities that come to mind. One could simply provide all of the required information as parameters to each service call.  Would it work? Yes. Is it a good idea? No. There are many reasons this is not a good solution. One concern is the added difficulty each client application would encounter trying to consume the SOA. Plus, the SOA would be confusing, difficult to implement and not very readable as a programmer. To me, building your SOA must always consider the consuming applications and the ease with which the services can be consumed as a high priority. Those alone point us directly to the messaging interface for the service. My initial thought was to create custom incoming and outgoing message header properties to allow C# windows clients to attach the properties directly via their client proxy and then dynamically read them out in the service layer. This allows all additional difficulty to be encapsulated within the client proxy/channel factory classes. This also allows non-windows users to dynamically build message headers and attach them to the calls coming into WCF while allowing the service to leverage a single implementation to pull the information out of the message. I needed to create a proof of concept application to illustrate this. I was wrapped up in another project at the time, so ToddM took the project on and delivered an illustrative project. (Thanks, Todd). An overview of the successful prototype is as follows. First, you have to attach the outgoing behavior message header at the channel factory level in C#. This requires the creation of CustomServiceOutgoingBehvaior and CustomServiceIncomingBehvaior classes based on IEndpointBehavior and Attribute, IServiceBehavior respectively. These are then attached to the DataChannel and inspected on either side of the communication. In an effort to make this post shorter and more readable, I have removed code that doesn't directly support the main idea. To be clear, these snippets on their own are not enough.

public class DatabaseInfo
{
  public String Catalog { get; set; }
  public String Instance{ get; set; }
}
public static class Tenant
{
    public static String TenantID { get; set; }
    public static String AuthenticatedUser { get; set; }
}

public class CustomClientOutgoingBehvaior : IEndpointBehavior
{
   void IEndpointBehavior.ApplyClientBehavior(ServiceEndpoint endpoint,
              ClientRuntime clientRuntime)
    {
        clientRuntime.MessageInspectors.Add(new CustomClientOutgoingMessageInspector());
    }

}

public class CustomServiceOutgoingBehvaior : IEndpointBehavior
{
    DatabaseInfo info = null;

    public CustomServiceOutgoingBehvaior(DatabaseInfo info)
    {
        this.info = info;
    }

  
    void IEndpointBehavior.ApplyClientBehavior(ServiceEndpoint 
              endpoint, ClientRuntime clientRuntime)
    {
        clientRuntime.MessageInspectors.Add(new CustomServiceOutgoingMessageInspector(info));
    }
}

public class CustomServiceIncomingBehavior : Attribute, IServiceBehavior
{
    void IServiceBehavior.ApplyDispatchBehavior(ServiceDescription
           serviceDescription, ServiceHostBase serviceHostBase)
    {
        foreach (ChannelDispatcher channelDispatcher in 
         serviceHostBase.ChannelDispatchers)
        {
            foreach (var endpointDispatcher in channelDispatcher.Endpoints)
            {
                endpointDispatcher.DispatchRuntime.
                     MessageInspectors.Add(new 
                     CustomServiceIncomingMessageInspector());
            }
        }
    }
}
public class CustomClientOutgoingMessageInspector : IClientMessageInspector
{
   object IClientMessageInspector.BeforeSendRequest(ref Message 
     request, IClientChannel channel)
    {
        var messageHeader = new MessageHeader<String>(Tenant.TenantID);
        var untypedMessageHeader = 
               messageHeader.GetUntypedHeader("TenantID", "Namespace.Shared");
        request.Headers.Add(untypedMessageHeader);

        messageHeader = new MessageHeader<String>(Tenant.AuthenticatedUser);
        untypedMessageHeader = 
              messageHeader.GetUntypedHeader("AuthenticatedUser", "Namespace.Shared");
        request.Headers.Add(untypedMessageHeader);

        return null;
    }
}

public class CustomServiceOutgoingMessageInspector : IClientMessageInspector
{
    public DatabaseInfo DatabaseInfo { get; set; }

    public CustomServiceOutgoingMessageInspector(DatabaseInfo info)
    {
        DatabaseInfo = info;
    }
  
    object IClientMessageInspector.BeforeSendRequest(ref Message request, IClientChannel channel)
    {
        if (DatabaseInfo == null)
            return null;

        var messageHeader = new MessageHeader<String>(DatabaseInfo.Catalog);
        var untypedMessageHeader = 
            messageHeader.GetUntypedHeader("Catalog", "Namespace.Shared");
        request.Headers.Add(untypedMessageHeader);

        messageHeader = new MessageHeader<String>(DatabaseInfo.Instance);
        untypedMessageHeader = 
            messageHeader.GetUntypedHeader("Instance", "Namespace.Shared");
        request.Headers.Add(untypedMessageHeader);

        return null;
    }
}
 
Then, with a simple function added to a base class for your WCF services, you will be able to pull this information back out as follows:

protected Tuple<DatabaseInfo, Tenent> GetInfoFromHeader()
{
    DatabaseInfo dbInfo = new DatabaseInfo();
    Tenant tenantInfo = new Tenant();

    Int32 i = OperationContext.Current.IncomingMessageHeaders.FindHeader("Catalog", "Namespace.Shared");

    if (i != -1)
        dbInfo.Catalog = OperationContext.Current.IncomingMessageHeaders.GetHeader<String>(i);

    i = OperationContext.Current.IncomingMessageHeaders.FindHeader("Instance", "Namespace.Shared");

    if (i != -1)
        dbInfo.Instance = OperationContext.Current.IncomingMessageHeaders.GetHeader<String>(i);

    i = OperationContext.Current.IncomingMessageHeaders.FindHeader("TenantID", "Namespace.Shared");

    if (i != -1)
        tenantInfo.TenantID = OperationContext.Current.IncomingMessageHeaders.GetHeade<String>(i);

    i = OperationContext.Current.IncomingMessageHeaders.FindHeader("AuthenticatedUser", "Namespace.Shared");

    if (i != -1)
        tenantInfo.AuthenticatedUser = OperationContext.Current.IncomingMessageHeaders.GetHeader<String>(i);


    return new Tuple<DatabaseInfo, Tenent>(dbInfo,tenantInfo);
}
 
At this point, you will be able to pull out information from the message header and perform many routines based on a tenant entity without adding state to the server. With this information, you can build connection strings for each DAL method pointing to the correct catalog and instance based on tenant.  You can also perform user security functions based on the AuthenticatedUser passed from the client.  As you can see, this is very flexible and would scale out to any values that needed to be communicated along with the messages to the service.

Tuesday, August 7, 2012

JQueryMobile List Item Helper

I have been working through some mobile web prototypes recently using jQueryMobile.  The mobile web application itself is a client of WCF services.  As part of the application I wanted to use the basic linked list format with some additional information.  Since these have to be attached to the DOM and rendered on the client side, I found myself wanting to retrieve a list of data contracts on the server side and have the DocumentReady function turn them into a linked list. Since the server side page_load code executes prior to the DocumentReady code on the client side, it gives us the opportunity to retrieve the data needed and place items in the DOM for linked list creation.  I found a viable solution for accomplishing this task and thought it seemed like a good item to walk through.

jQueryMobile list anatomy
The list markup is fairly straightforward and has additional attributes for data-role to drive jQueryMobile.  Here is a snippet for a small sample list:

<div data-role="content">
  <div class="content-primary">
    <ul data-role="listview">
    <li><a href="index.html">Acura</a></li>
    <li><a href="index.html">Audi</a></li>
    <li><a href="index.html">BMW</a></li>
    <li><a href="index.html">Cadillac</a></li>
    <li><a href="index.html">Chrysler</a></li>
    <li><a href="index.html">Dodge</a></li>
    <li><a href="index.html">Ferrari</a></li>   
    </ul>
  </div>
</div>

This all works really well if you can hard-code the items in your list, which in this case I could not.  The number of items had to be dynamic as well as the href attribute.  In order to accomplish this, I made the following modifications to the snippet:
<div data-role="content">
  <div class="content-primary">
    <ul runat="server" id="carList" data-role="listview">
    </ul>
  </div>
</div>

In short, I made the control run at the server, gave it an id and removed all of the items from the list.  So my next step is to dynamically add the items to the list from the C# code behind.  The first thing to do was create a helper object to create items for me.  I wanted to be able to dynamically format these items to have a header, details and possibly a thumbnail image.  In order to accomplish this, I had this class take a title, a list of strings, the href location and an image if one was required.  Here is the helper code I used:
public static class jQueryMobileHelper
{
public static HtmlGenericControl buildListItem(String headerDescription, 
    List<String>items, String urlLocation)
{
  HtmlGenericControl li = new HtmlGenericControl("li");
  HtmlGenericControl anchor = new HtmlGenericControl("a");
  HtmlGenericControl h3 = new HtmlGenericControl("h3");
  anchor.Controls.Add(h3);
  h3.InnerText = headerDescription;
  foreach (String detail in items)
  {
    HtmlGenericControl p = new HtmlGenericControl("p");
    p.InnerText = detail;
    anchor.Controls.Add(p);
  }
  anchor.Attributes.Add("href", urlLocation);
  anchor.Attributes.Add("target", "_self");            
  li.Controls.Add(anchor);
  return li;
}

public static HtmlGenericControl buildListItemWithThumbnail(String headerDescription, 
     List<String>items, String urlLocation, String imageLocation)
{
  HtmlGenericControl li = new HtmlGenericControl("li");
  HtmlGenericControl anchor = new HtmlGenericControl("a");
  HtmlGenericControl h3 = new HtmlGenericControl("h3");
  HtmlGenericControl img = new HtmlGenericControl("img");

  img.Attributes.Add("src", imageLocation);
  img.Attributes.Add("style", "height: 70px; width: 70px");
  img.Attributes.Add("display", "inline-block");
  img.Attributes.Add("alt", "image");

  anchor.Controls.Add(img);
  anchor.Controls.Add(h3);
  h3.InnerText = headerDescription;
  foreach (String detail in items)
  {
    HtmlGenericControl p = new HtmlGenericControl("p");
    p.InnerText = detail;
    anchor.Controls.Add(p);
  }
  anchor.Attributes.Add("href", urlLocation);
  anchor.Attributes.Add("target", "_self");
  li.Controls.Add(anchor);
  return li;
}
Next I looped through the items I had in my collection and created the list items.  As part of this routine, I just appended the items to the list control as follows:

List<String>items = new List<String>();
foreach (CarInfo car in cars)
{
   items.Add(car.Make);
   items.Add(car.ModelYear);
   items.Add(car.Price.ToString("C"));
   carList.Controls.Add(jQueryMobileHelper.buildListItemWithThumbnail(car.Model,items,
          String.Format("carDetail.aspx?carId={0}",car.ID),
          car.ThumbnailLocation ));
}
This gives you a list formatted similarly to the examples on the jQueryMobile site.  But, allows you to build them dynamically from the server side based on your existing services.

Friday, July 27, 2012

Ordinals vs Column Names - Part Deux

Since the first post turned into a discussion of readability versus performance, maintainability versus speed and other very worthwhile topics, I decided to put this entire process to a road test.  I created unit tests that called a DAL services basically retrieving an entire table in each of the three presented methodologies.  To get the output, I enabled our handy-dandy unit test timer to trap the performance of the DAL list functions. In order for this to be good science, I restarted the database 3 times over the course of the testing and ran the tests in different orders each time. For retrieving just under 17000 rows consisting of 38 columns, here are the results and averages for the test run (values in Milliseconds).


Run  String  Dictionary Ordinal String Order Dictionary Order Ordinal Order Difference
1 2705 2469 2505 1 3 2 236
2 2648 2575 2506 2 3 1 142
3 2669 2520 2501 2 1 3 168
4 2570 2648 2445 3 1 2 203
5 2577 2566 2397 3 1 2 180
6 2450 2646 2575 3 1 2 196
7 2555 2606 2479 2 1 3 127
8 2843 2621 2446 1 2 3 397
9 2628 2485 2388 1 2 3 240
10 2580 2525 2400 3 1 2 180
Total 2622.50 2566.10 2464.20 0.21

So, at the end of the day, here is what I learned.  It really doesn't matter enough to worry about it.  Sure, the ordinals are consistently faster than the dictionary and the dictionary is faster than string, but the variance is hardly worth worrying about.  When retrieving 17000 rows, the average difference from the best performance to the worst performance was a matter of 2/10 of one second.  I think I got wrapped up in a common distraction know as micro-optimization, where we spend a ton of mental energy and rewrite code to gain a millisecond on a routine. Yes, you should care about performance, and yes, faster code should always be your goal, but there comes a point in time where it stops being worth the development time.  Yes, we should avoid the blatantly poor performing code mistakes that everyone knows about. But after that, we should be equally worried about the scalability, portability, maintainability and readability of our code. We should ask if saving 2/10 second while retrieving 17000 rows is the matter to discuss, or should we be discussing why we would ever be retrieving 17000 often enough in our application to have 2/10 second be an issue.  Yes, I started the discussion, thinking it was a creative way to gain performance.  Honestly, I enjoy trying to work through things like this too, which fed the distraction.  I believe now that these mental exercises should always be framed with realistic improvement potential weighed against the time and effort of the pursuit. At that point, only pursue until it starts becoming a net loss of productivity.  On this particular subject, after doing this research, count me firmly in the "It really doesn't matter, aim at code readability and object design" camp.

Tuesday, July 24, 2012

Synchronization Context and Callbacks

SynchronizationContext 
The SynchronizationContext behavior is basically a configuration that allows the asynchronous and synchronization operations of the CLR to act appropriately while being used within various synchronization models. It also allows for a simple configuration of applications to work correctly under the different synchronization environments. This gives a service a quick way of associating itself with a particular synchronization context and then allowing WCF to detect that context and automatically marshal the call from the worker thread to the service synchronization context. The default value of UseSynchronizationContext is true. Affinity between the service, host and synchronization context is set when the host is opened. If the thread opening the host has a synchronization context and UseSynchronizationContext is true, WCF will establish an affinity between that synchronization context and all instances of the service hosted by that host. WCF will automatically marshal all incoming calls to the synchronization context. If UseSynchronizationContext is false, regardless of any synchronization context the opening thread might have, the service will have no affinity to any synchronization context. Interestingly enough, if UseSynchronizationContext is true but the opening thread has no synchronization context, the service will still not have one. By default, when executing the code below the client thread will be blocked while the return value is received from the service.

serviceProxy = new SomeService(new InstanceContext(this));
serviceProxy.Open();
MyObject = serviceProxy.CreateMyObject(new MyObject(1));

This is all fine on the surface. But, what would happen if the CreateMyObject function sends a callback? The client thread would be blocked. We can handle this with the callback behavior aspect of WCF. CallbackBehaviorAttribute.

UseSynchronizationContext
As a refresher, the CallbackContract property of a ServiceContract specifies the interface to define callback operations. This will create a dependent relationship between the interfaces. Once a CallbackContract is specified, the client will have to implement the callback functions in order to interact with the service at all. The CallbackBehavior setting for UseSynchronizationContext basically governs the affinity between the service and the client. You can easily override the automatic association of synchronization contexts with a simple decoration. By setting the UseSynchronizationContext property of the CallbackBehavior attribute to false, WCF will no longer guarantee a particular thread to be responsible for processing service requests. Instead, the operations will be automatically delegated to worker threads.

[CallbackBehavior(UseSynchronizationContext = false)]

When not using synchronization context on callback behavior, you may run into issues trying to directly update the UI, since those callbacks will no longer be on the UI thread.  One way around that would be to use a SendOrPostCallback delegate.