Part 1. Harnessing the power of IExtensibleDataObject

One of the first things people tend to do when there are building an application (at least I do!), is try to identify the models (POCO’s) which will be used throughout the application.  Because we added a service refence to WCF service provided by Micorsoft, a base for the models are already provided.  I created a class diagram to give some more insight on the way the models are constructed.

 

 This class diagram shows us a couple of things. First of all, we have a base class which serves as a base for all the possible tag types. A more important observation is that this base class implements the IExtensibleDataObject interface (http://msdn.microsoft.com/en-us/library/system.runtime.serialization.iextensibledataobject.aspx ).  The implementation of this interface ensures us that the properties marked with the DataContractAttribute attribute are preserved while serializing and deserializing. Even better, when serialized to a parent or child class the data is preserved in the ExtentionData property provided by the interface.

At this moment we have successfully identified the main part of the models provided by the API. It is now time to make sure we can take advantage of these models and their behavior. In some cases you can use the models as-is and you can build your software on top of the base classes provided but more often you’ll need some additional properties on the model to make it usefull for this specific environment.

For this post I’ll extend the base classes with a minimal amount of properties, so we can use these properties in Part 3 of this multi-post. I usually work a lot with interfaces and abstracts to minimize the amount of duplicate code and minimize the risk of built-in dependencies. In this case I’ll introduce a couple of interfaces and an extension method  to work with the IExtensibleDataObject interface.

 

 

 

As you can see in this class diagram, all extended objects implement an interface which inherits from ITag and they inherit from the classes provided by the API.  The ITag interface inherits from the IExtensibleDataObject in order to accommodate the extension method.  The concrete (and simple!) implementation of UriTagExtended looks like this:

The next step is to implement an extension method which allows us to go back and forth to the base object and our extendedobject. The extension method hooks in on the IExtensibleDataObject interface and equips every class inheriting from that interface with an additional method: ConvertTo<T>. This extension serializes the object and deserializes it into T (and store any additional info in the DataExtension property). Our extension method is implemented as follows:

 

 

 

With the implementation of our extension method we are able to revert our extended objects back to the base objects that are supplied to the methods of the API.   In the next part of this multi-part blog post I will wrap the API in a repository pattern and make some more use of the extended properties and the extension method we created.  

Tagged , ,

Building Software using the Microsoft Tag API

A recent chat with Ken Levy from Code magazine, inspired me to write this multi-part blog on Tagging.
Microsoft Tag is Microsoft’s answer on the growing adoption and use of QR codes. While QR codes are a common technology in Asia, the people in Europe (and as I understood also in the US) are getting up to speed with the technology right now.

For the people who don’t know what a QR code is, a small introduction can be helpful to understand it’s potential. Microsoft describes a Tag as: “a new kind of bar code that connects almost anything in the real world to information, entertainment, and interactive experiences on your mobile phone. Tags are free to create and use. You can add them to your ads, posters, product packages, display it on your website, billboards, clothing…” (source: http://tag.microsoft.com )

To be able to use the Tags, people need to download the Microsoft Tag reader app by downloading it from http://gettag.mobi (browse to this site using your mobile phone).  When a tag is scanned, the phone will open a webpage, download a v-card, receive a text message, or dial a number.  Microsoft provides a ready to use Tag manager, but in some cases you would like to create Tags programmatically.

Microsoft lets you register for the tag manager and you can get access to their API, which is actually a WCF service. Although this is great, some things need to be overcome to work efficiently with the API. The API lets you create, manipulate and retrieve single tags. It is however, not possible to search or delete a Tag using the API.  Although this might sound as a big disadvantage we can turn it around and make it into an opportunity.

The “missing” functionality in the API forces developers to create local storage to make the tags searchable. By choosing the right Architecture and technologies we can develop a flexible implementation of the API which can connect to any Storage with minimal effort.  This blog consists of four parts, where every part will present a solution or approach to work with the API.

Part 1. Harnessing the power of IExtensibleDataObject
Part 2. Wrapping the service in the Repository Pattern
Part 3. Reading the .Tag format
Part 4. Decouple the Persistor with Dependency Injection

Tagged

Filter GroupList Based on Permissions of a Role

In a past project i was asked to build a Grouplist like widget for Community Server. This Grouplist widget was different from the existing because the data should be filtered by the permissions of a role (in my case Members). i have searched for a standard way to do this with the existing controls but eventually i had to write my own  <CSControl:CustomCondition />. i implemented the widget as follows (staying closely to the existing widget implementation in CS 5.5).

<%@ Control Language=”C#” AutoEventWireup=”true” %>

<%@ Import Namespace=”System.Collections.Generic” %>
<%@ Import Namespace=”System.Collections.ObjectModel” %>

<script runat=”server” language=”C#”>

    public bool IsApproved(CommunityServer.Components.Group group)
    {
     CommunityServer.Components.ISecurityService securityService = Telligent.Common.Services.Get<CommunityServer.Components.ISecurityService>();
     CommunityServer.Components.IRoleService roleService = Telligent.Common.Services.Get<CommunityServer.Components.IRoleService>();

        IEnumerable<CommunityServer.Components.Role> roles = roleService.GetRolesForGroup(group.ID);
 
     CommunityServer.Components.Role member = null;
     foreach(CommunityServer.Components.Role role in roles)
     {
      if(role.Name == “Members”)
      {
       member = role;
      }
     }
     if(member != null)
     {
      CommunityServer.Components.PermissionList p = securityService.GetImmediatePermissions(group.NodeId);
     
      foreach(CommunityServer.Components.PermissionEntry m in p)
      {
       if(m.Name == “Community – Create New Communities” && m.RoleId == member.Id && m.IsAllowed)
       {
        return true;
       }
      }
     }
 
        return false;
    }
</script>

<CSControl:GroupData runat=”server” CssClass=”content-item simple” Tag=”Li”>
 <DisplayConditions Operator=”And”>
  <CSControl:CustomCondition 
     CustomResult=”<%# IsApproved(CSControlUtility.Instance().GetCurrentGroup(Container)) %>” 
     runat=”server” />
  </DisplayConditions>   
    <ContentTemplate>
        <CSControl:GroupData runat=”server” 
           Property=”Name”
           TruncateAt=”25″
           LinkTo=”HomePage” />
    </ContentTemplate>
</CSControl:GroupData>

 

Randomize Userlist for Telligent Community Server

Recently i was asked to build a UserControl that uses the UserList of Community Server and randomizes the order of the items. I guess the best solution would be extending the QueryOverrides and provide a Randomizer QueryType. Sometimes this solution is not an option and you need a workaround. In this solution we ta into the PreRender event of the UserList and shuffle the datasource and call on databind. I do realize that calling DataBind in the prerender event of a control can cause serious problems but for the UserList this will not be the case.

Using Moles to isolate Deserialization of HttpResponse of Twitter API.

Moles (download link) is introduced by the Microsoft Research Team to help isolate .NET code. With moles you can replace any method from external resources to help you focus on the specific piece of code you want to test. In this blog I will show its usefulness of this add-in with a piece of code that uses the HttpClient and its extensions provided by the WCF starter kit (reference video). In this blog i use some simple code that calls on the Twitter API to get the messages from a specific twitter profile. In the code, there is a class called TwitterConnector with a public method called StatusTimeLine().

public class TwitterConnector
{
 /// <summary>
 /// Retrieves a timeline for the authenticated user or id. 
/// </summary>
public TwitterMessageCollection StatusTimeLine()
{
    HttpClient client = new HttpClient(“http://twitter.com/statuses/&#8221;);
    client.TransportSettings.Credentials = new NetworkCredential(“usr”, “pwd”);
    ServicePointManager.Expect100Continue = false;

    HttpResponseMessage response = client.Get(“home_timeline.xml”);
    response.EnsureStatusIsSuccessful();

    return response.Content.ReadAsDataContract<TwitterMessageCollection>();
}

The TwitterMessageCollection is defined as follows

[CollectionDataContract(Name = "statuses", ItemName = "status")]
public class TwitterMessageCollection : ICollection<TwitterMessage>{}

And TwitterMessage is defined as
[DataContract(Name = "status")]

public class TwitterMessage
{
[DataMember(Name = "id")]
    public string Id { get; set; }

    [DataMember(Name = "text")]
    public string Text { get; set; }

    [DataMember(Name = "screen_name")]
    public string Name { get; set; }

    [DataMember(Name = "user")]
    public TwitterProfile User { get; set; }
}

The specific feature i would like to test is ReadAsDataContract which will validate our DataContract definition in TwitterMessageCollection and TwitterMessage. The Twitter API counts the number of calls made to the REST API for a specific account and limits it. When doing development you don’t want to be limited in your number of calls. For this particular case we can mole the call and response. Hence, we pretend getting a response using Moles and Pex. Before we can start working with Moles we need to create a .moles file which is created from any dll. This file will provide our test with fake (mole) objects. For a explanation on how to create the .moles files you need to review the Moles documentation.

To start creating the test which will fake our call we right-click inside our original method and choose Pex -> Create Parameterized Unit Test from the context menu. Follow the instructions on the screen and the add-in will add a new project to your solution containing the Unit Test.

If you open the new test class in the new project you’ll find a method that will look similar to:
/// <summary>Test stub for StatusTimeLine()</summary>
[PexMethod]
public TwitterMessageCollection StatusTimeLine([PexAssumeUnderTest]TwitterConnector target)
{
     TwitterMessageCollection result = target.StatusTimeLine();
     return result;
}

The first thing we need to do is to trap the HttpClient to make sure Pex will notify us when we call on any method or property from the HttpClient that is not moled.

/// <summary>Test stub for StatusTimeLine()</summary>
[PexMethod]
public TwitterMessageCollection StatusTimeLine([PexAssumeUnderTest]TwitterConnector target)
{
      //trap the client
      MHttpClient.BehaveAsNotImplemented();

     //invoke our method as we would in a regular case.
     TwitterMessageCollection result = target.StatusTimeLine();

     //return the result.
      return result;
}

If we run the Pex Exploration of this test by right-clicking inside the test and choose Run Pex Explorations. Pex will give us the first object that is trapped as MoleNotImplemented. In our case this will be:

MoleNotImplementedException, HttpClient.HttpClient(String) was not moled.

This exception is a good thing because Pex is telling us that the HttpClient we wanted to fake was not moled. We can mole the HttpClient by adding the following code

 /// <summary>Test stub for StatusTimeLine()</summary>
[PexMethod]
public TwitterMessageCollection StatusTimeLine([PexAssumeUnderTest]TwitterConnector target)
{
      //trap the client
      MHttpClient.BehaveAsNotImplemented();

     //mole constructing the httpclient
      MHttpClient.ConstructorString = (client, url) =>
      {
            //instance of the new client
            new MHttpClient(client){};
      };

     //invoke our method as we would in a regular case.
     TwitterMessageCollection result = target.StatusTimeLine();

     //return the result.
      return result;
}

ok, now we have moled the client and we can ask Pex to explore the test again and try to run our Test again. The exploration will give us another exception.

MoleNotImplementedException, HttpClient.get_TransportSettings() was not moled.

If we look at our original code this makes sense:
HttpClient client = new HttpClient(“http://twitter.com/statuses/&#8221;);
client.TransportSettings.Credentials = new NetworkCredential(“usr”, “pwd”);

after constructing our client we call on a property to set the TransportSettings and its credentials. Because of our trap, we need to mole this property too. We can do this by adding the following code to the test. The code actually moles the get property of the TransportSettings and the set property of the credentials of these TransportSettings.

MHttpClient.ConstructorString = (client, url) =>
{
     //instance of the new client
     new MHttpClient(client)
     {
            //mole the transportsettings
            TransportSettingsGet = () => new MHttpWebRequestTransportSettings()
            {
            CredentialsSetICredentials = (credential) => new System.Net.Moles.MNetworkCredential(credential.GetCredential(new Uri(_url), “Basic”))
            }
     };
}

We are almost there but not quite yet. If we run the exploration again we will encounter yet another exception.

failing test: MoleNotImplementedException, HttpClient.Send(HttpMethod, Uri) was not moled.

This is the method we were after. This is the actual call to the API we needed to intercept. We can mole this specific call by adding our last piece of code to the puzzle.

//Subsitute Call and Response
new MHttpClient(client)
{
                    //mole the transportsettings
                    TransportSettingsGet = () => new MHttpWebRequestTransportSettings()
                    {
                        CredentialsSetICredentials = (credential) => new System.Net.Moles.MNetworkCredential(credential.GetCredential(new Uri(_url), “Basic”))
                    },
                    //mole the send method (invoked by .Get())
                    SendHttpMethodUri = (method, uri) =>
                    {
                        //mole the response
                        return new MHttpResponseMessage()
                        {
                            //set the statuscode to OK
                            StatusCodeGet = () => { return System.Net.HttpStatusCode.OK; },

                            //mole dispose
                            Dispose = () => { },

                            //fake return
                            ContentGet = () => { return HttpContent.Create(_xml); }
                        };
                    }
                };
}

By adding the mole for the Send method we can intercept the invocation and send our own response to the serializer. I copied the xml from the Twitter API documentation into a resource file. the contents of the xml is returned as the response by ContentGet = () => {return HttpContent.Create(_xml);} because of our code before calling

//invoke our method as we would in a regular case.
TwitterMessageCollection result = target.StatusTimeLine();

The Twitter API is not used but the  response provided by the mole is used in

return response.Content.ReadAsDataContract<TwitterMessageCollection>();

One final problem we need to overcome is the maximum number of branches Pex can explore. We can set the maximum by adding a attribute to the PexMethod.

/// <summary>Test stub for StatusTimeLine()</summary>
[PexMethod(MaxBranches = 40000)]
public TwitterMessageCollection StatusTimeLine([PexAssumeUnderTest]TwitterConnector target)
….

Personally I like to create my own assertions in another TestMethod based in the same class. My simple Test looks like this:
[TestMethod]
[HostType("Moles")]
public void CanDeserializeIntoMessageCollection()
{
            //invoke our pex/moles method
            TwitterMessageCollection result = StatusTimeLine(new TwitterConnector());

            Assert.IsNotNull((object)result, “Deserialization Failed”);
            Assert.AreEqual<int>(2, result.Count, String.Format(“Expected 2 users but Found {0}”, result.Count));

            foreach (TwitterMessage msg in result)
            {
                     Console.WriteLine(“{0}”, msg.Id);
            }
        }

Important is the HostType attribute. This tells the framework to look for moles. Without this attribute your TestMethod will not run.

Follow

Get every new post delivered to your Inbox.