Smart House Alerts

August 25, 2011 at 9:15 AMmgordon

Bad weather on the way? My Smart House let's me know. I have an appointment this afternoon? It lets me know. A favorite blog has an update? Yep.

I decided early on that I wanted my smart house to notify me of some things. As a result, the time I used to spend checking the weather site, checking for blog updates, checking my calendar is now free time. These things are pushed to me, now, by my smart home.

The system has a series of alerts that do little more than poll various end-points or database records on timers. When conditions are such that I need to be notified, I get a message.

How does the application know how to reach me? Well, a couple of ways. In my system, there is a concept of a communication channel. This channel is associated with a particular user of the system and a certain mode of communication (IM, SMS, email, more to come). When I log into IM, for example, the system knows I'm online and that channel is marked as being open. If an alert occurs, it knows I can be reached on that channel.

For other channels, such as email and SMS, the channel always remains open. For these, I can configure the application to notify me on that channel or not depending on the alert.

IM

I use the XMPP protocol for IM communication with my Smart House. This allows me to use Google Talk or Jabber to get messages from or send messages to the system. I have taken a dependency on the the XMPP SDK from Ags. It allows me to connect to the network, to be notified when any of the Smart House's buddies go on or off line, and to send and receive messages.

Connecting is simple. First, instantiate and configure a connection.

Connect to XMPP
  1. Conn = new XmppClientConnection(ConfigurationManager.AppSettings["XmppServer"]);
  2. Contacts = null;
  3. Contacts = new List<Contact>();
  4. Conn.EnableCapabilities = true;
  5. Conn.ClientSocket.ConnectTimeout = 60000;
  6. Conn.AutoResolveConnectServer = false;
  7. Conn.ConnectServer = "talk.google.com";
  8. Conn.Port = int.Parse(ConfigurationManager.AppSettings["XmppPort"]);
  9. Conn.UseStartTLS = false;
  10. Conn.UseSSL = true;

Then, add some event handlers.

Set Event Handlers
  1. Conn.OnError += conn_OnError;
  2. Conn.OnMessage += conn_OnMessage;
  3. Conn.OnPresence += _conn_OnPresence;
  4. Conn.OnLogin += s =>
  5. {
  6. IsConnected = true;
  7. var p = new Presence(ShowType.chat, "Online") { Type = PresenceType.available };
  8. Conn.Send(p);
  9. };
  10. Conn.OnAuthError += (s, e) => StructuredSpeech2.Logging.Logging.Log("XMPP Authentication Error");
  11. Conn.OnRegisterError += (s, e) => StructuredSpeech2.Logging.Logging.Log("XMPP Register Error: " + e.InnerXml);
  12. Conn.OnSocketError +=
  13. (s, e) =>
  14. StructuredSpeech2.Logging.Logging.Log("XMPP Socket Error: " + e.Message + " :: " + e.StackTrace);
  15. Conn.OnStreamError += (s, e) => StructuredSpeech2.Logging.Logging.Log("XMPP Stream Error: " + e.InnerXml);

Finally, connect.

Connect
  1. try
  2. {
  3. Conn.Open(ConfigurationManager.AppSettings["XmppUsername"],
  4. ConfigurationManager.AppSettings["XmppPassword"]);
  5. }
  6. catch
  7. {
  8. Initialize();
  9. }

Notice that many of the event handlers we're handling have to do with various things that can go wrong. There are logged for investigation later. The OnLogin event fires when a connection to the network has been established. Here, I'm setting the system's status to online and available.

When a login fails, we recurse and try again.

The OnPresence event fires when the presence status of a user has changed such as their becoming available or signing off. The event args let us know the buddy and what their new presence value is. When I handle this event, I evaluate the new presence value and then do two things. I keep a collection of all online contacts so I can quickly broadcast a message. The first thing I do when I get a presence event is to update this collection by adding or removing the contact as appropriate. The second thing I do is update the state of the communication channel for the user the buddy represents.

The OnMessage event fires when a message has been received from a buddy. The event arguments specify the the buddy the message is from and the text of the message. When a message is received, I check to see that the buddy is a user on the system and if they are, I process the message with the Language Processor. If the user is not found, a response is sent to the buddy stating they are not a known user and cannot interact with the system.

Finally, I can send a message to any online buddy by calling the send method on the connection class. As with the the previous discussions about the Speech Processor, the entire conversation is logged and used in processing the text sent in a particular message. In the case of IM, the conversation starts when the buddy connects to the network and ends when they disconnect. When a message has been received, the Language Processor processes it and then uses this send method to reply to the appropriate user. Alerts are send in the same way.

The bottom line is that I can send commands to my house via IM and have it act appropriately or it can send me messages to alert me if my attention is needed. A true conversational interface.

Email

I'm using OpenPop to provide the functionality need to check and manipulate emails on the POP server. My Smart House has it's own email account which it polls on a timer. Each time, all messages are pulled from the email account, processed and then deleted. OpenPop allows the system to connect to the pop account and pull down all the messages. First, the connection object is created and configured.

Connect to POP3 account
  1. _client = new Pop3Client();
  2. _client.Connect(_popEmailServer, _popEmailPort, _popEmailUseSsl);
  3. _client.Authenticate(_popEmailUname, _popEmailPassword);
  4. _client.Reset();

Next, the messages are pulled down and processed.

Process Email Messages
  1. _emailCheckTimer.Stop();
  2. try
  3. {
  4. ConnectClient();
  5. if (!_client.Connected)
  6. return;
  7. int messageCount = _client.GetMessageCount();
  8. var messages = new List<Message>(messageCount);
  9. for (int i = 1; i <= messageCount; i++)
  10. {
  11. messages.Add(_client.GetMessage(i));
  12. _client.DeleteMessage(i);
  13. }
  14. List<Message> staticMessages = messages;
  15. var enc = new ASCIIEncoding();
  16. foreach (Message msg in staticMessages)
  17. {
  18. string request = enc.GetString(msg.FindFirstPlainTextVersion().Body);
  19. string fromAddress = msg.Headers.From.Address;
  20. User user = UserRepository.GetUserByEmail(fromAddress);
  21. if (user == null)
  22. {
  23. SendResponse("I don't know this email address.", msg.Headers.From.Address, msg.Headers.Subject);
  24. return;
  25. }
  26. if (_client != null)
  27. {
  28. _client.Disconnect();
  29. _client.Dispose();
  30. }
  31. CommandProcessor.ProcessCommand(request, user, ConversationMode.Email, fromAddress);
  32. }
  33. }
  34. catch (Exception ex)
  35. {
  36. StructuredSpeech2.Logging.Logging.Log("Checking mail " + ex.Message + ex.StackTrace);
  37. }
  38. finally
  39. {
  40. if (_client.Connected)
  41. _client.Disconnect(); ;
  42. _client.Dispose();
  43. }
  44. _emailCheckTimer.Start();

For sending emails, I use the SmtpClient class in the .Net Framework. See its documentation for usage.

SMS

Once email has been implemented, SMS is easy. I use SMS for outgoing messages, only. Most cell phone carriers allow SMS messages to be send via email. For example, an email sent to an address such as 10digitnumber@txt.att.net, will be received as an SMS message on the AT&T network phone having that 10 digit number. For this reason, I use exactly the same approach to send SMS messages as I do for sending emails.

Posted in: .Net | Smart Home | Natural Language Processing

Tags: , ,

Letting My Smart Home Keep a TODO List for Me

August 25, 2011 at 5:26 AMmgordon

In my last post, I summarized how I created a Natural Language Processor around which I am building a Home Automation solution. I want my smart home to be able to more than just turn things on an off, so I have been adding pieces of functionality that will automate more than that. The first piece of functionality I added was the ability to create and manage items on a TODO list.

Add the Tokens

If you'll recall from my last post, the language processor contains several Token classes that know how to parse out and tokenize words or phrases. These classes are the building blocks which are used to define the system's vocabulary. For the TODO list functionality, we need to define Token classes for the following:

  • "todo"
  • "list", "get", "show"
  • "create"
  • "delete"
  • "mark"
  • "done"
  • "for", "on"
  • dates and times

The language processor will parse the command we specify into a list of tokens that will be compared to the parameter lists of our command methods. When a match is found, that method is called. We need to define our command methods, next.

Create the Command Methods

In the end, we are wrapping little more than CRUD operations for a TODO list table in the database. One example of a command method is below.

Code Snippet
  1. public static void CreateNewToDoItem(ConversationContext cContext, TokenCreate create, TokenToDo todo, TokenQuotedPhrase phrase)
  2. {
  3. var repos = new ToDoRepository();
  4. var newTodo = repos.CreateNewTodo((string)phrase.Value, null, cContext.ConversationUser.UserId);
  5. cContext.Say("Added ToDo \"" + phrase.Value + "\"", newTodo);
  6. }

 

This method takes a token for "create", one for "todo" and another for a quoted phrase which is any phrase found between quotes. So an example of a command that might result in this method's being called would be

create a new todo "Call the hardware store about paint"

You can see that when the method is executed, a new record is created for the todo item. The first parameter is the conversation context. This context contains information such as what channel the communication is on (IM, email, etc.), the user being conversed with and a list of incoming and outgoing messages in this conversation. This is important in some cases. Consider when the user wants to delete a todo item. We could allow them to specify the item by its text, but that could be error prone and a lot of typing. It'd be better if they could specify only a number. So, in my implementation, the user requests a list of their items and what is returned is a numbered list. The user can then say, "delete 2" to remove the second item.

How does the system know which item was number 2? When the list is generated, it's stored in the context such that 2 corresponds to a particular item. From that point on, it doesn't matter what else happens to the records in the database because 2 doesn't just mean the second item, but the item that was second in that list at that point in time. This is possible because of the context.

The reply to the user gets sent to the right user through the right channel because of the context. In this implementation, we don't have to worry about these details in the command method, the context keeps it sorted out for us.

By repeating the process of creating the necessary tokens to build up our vocabulary and then creating rules to match, functionality is layered onto the system to allow the user to associate a due date and time with the item,

create new todo "call the insurance man" for tomorrow 1:30

Posted in: .Net | Smart Home | Natural Language Processing

Tags: , ,

Natural Language Processing

June 15, 2011 at 10:05 AMmgordon

I can’t remember a time when I didn’t have an interest in home automation.  Finally, I decided to take the plunge and started thinking about  what a system might look like.  At the top of my list of requirements was a way to communicate with the system in sentences…via email, SMS, IM and voice.

 

Requirements

What I had in mind was a something that would take what was input, figure out what was being asked for and then perform some action based on how the sentence was interpreted.  The system didn’t need to be able to figure out any possible sentence, but at the same time I didn’t want to have to remember an exact syntax for each command, so some flexibility needed to exist, as well.  Sense I predict the system will be expanded upon in an ongoing way, the addition of functionality and the commands to invoke it had to be relatively easy to add.

 

Existing Tools

I did a fair amount of research into what tools were available and invested a good deal of thought into how I might use them.  As for existing tools, I found that most (like Antelope and SharpNLP)  use maximum entropy to determine the meaning of a sentence.  They break down the sentence into its constituent parts such as phrases and words and define the part of speech each represents.  For each word, it’s also possible to look up its synonyms and definition.  I found that this approach, however, would be quite labor intensive to use.  Also, these tools, curiously, did not understand the concept of certain temporal phrases like “tomorrow” or “last Friday”.

I though these tools could be useful in that a command could be pre-processed and certain parts of it, like the verb and object, could be stored away.  Then, when a command was input, it could be processed and then compared with the stored information.

About this time, I came across Ian Mercer’s blog.  There, he describes an NLP engine that he has built and it became the inspiration for the engine I ended up building.

 

Step by Step

There are three steps I take in processing an input phrase or sentence, Tokenize, Organize and Evaluate.  The input is parsed and tokens are created for the recognized portions of the string.  These tokens are then grouped and organized into a particular order so they can be compared to method signatures defined  to represent recognized commands.   You’ll see that this approach also allows for a good deal of flexibility in how the command is expressed by the user.

 

Tokenize

There are several token classes defined and these are all instantiated at system startup.  Each is responsible for searching out one particular piece of text and correctly interpreting it. The token class also keeps track of where in the string the text was found and its length.  The token classes range in complexity from a simple text search to converting a piece of text into a DateTime or numeric value.  Each token class returns one or more TokenResult classes.  Each of these contains information about the text that was tokenized, where it was found, its length and its value.

The value returned depends on the text being tokenized.  For example, if the text “12” was found to be in the input by the TokenNumeric class, it would return an int, long and double with the value of 12.  It would also return an ordinal value indicating the 12th in a series and DateTime representing the 12th day of the current month. 

All of these Token classes inherit from a Token base class and are in class hierarchies of varying depths.  This allows for the use of polymorphism during the evaluation step.  We’ll see more about this later.

An example of a simple Token class would be the TokenTurn class:

 

[DataContract]
   public class TokenTurn : Token
   {
       public TokenTurn()
       {
           Words = new List<string> { "turn", "set" }; 
       }
   }

 

The base class, Token, defines the member variable “Words” and a method, “Parse”, that knows how to locate occurrences of any of the words in the Words collection.  So, in this decendant class, all that’s required is the definition of the strings to locate.  Once an occurrence is found, the TokenResult that’s returned notes the fact that it was a TokenTurn that located the string.  We’ll use this information later when we look for matching command definitions.  Notice that we have defined two words in our Words collection.  Since either could be found and in either case the meaning of the word would be interpreted as having the same meaning, we are in essence defining synonyms.  This is one way that flexibility is introduced.  For example, the user could say, “turn livingroom lamp on” or “set livingroom lamp on” and the command would be invoked the same way.

In some cases, another level of hierarchy exists.  One example is with the temporal tokens.  The TokenTemporal class knows about its own set of sub-tokens, if you will, that know how to parse bits and pieces of a Date or Datetime.  It cycles through each of these tokens and collects the token results.  It then evaluates them to determine a single date or time value.  This value, in turn, is passed back up the call chain to the main processing logic.

 

At system startup, all Token classes are located and instantiated using reflection.

 

private static List<Token> GetTokens()
       {
           var tokens = new List<Token>();
           var assemblies = new List<Assembly>();
           var currentAssembly = Assembly.GetExecutingAssembly();
           string path = currentAssembly.Location;

           foreach (string dll in Directory.GetFiles(Path.GetDirectoryName(path), "*.dll"))
           {
               try
               {
                   assemblies.Add(Assembly.LoadFile(dll));
               }
               catch (Exception)
               {
               }

           }

           foreach (var assembly in assemblies)
           {
               foreach (Type type in assembly.GetTypes())
               {
                   if ((type.Namespace == "StructuredSpeech2.Tokens.Nouns" ||
                        type.Namespace == "StructuredSpeech2.Tokens.Prepositions" ||
                        type.Namespace == "StructuredSpeech2.Tokens.Temporal" ||
                        type.Namespace == "StructuredSpeech2.Tokens.Verbs" ||
                        type.Namespace == "StructuredSpeech2.Tokens") &&
                       type.Name.StartsWith("Token") &&
                       type.Name != "TokenResult" &&
                       type.Name != "Token" &&
                       type.Name != "TokenNoun")
                   {
                       ConstructorInfo ci = type.GetConstructor(Type.EmptyTypes);
                       tokens.Add((Token)ci.Invoke(null));

                   }
               }
           }
           return tokens;
       }

When input is received, each token class in the collection has it’s “Parse()” Method called and the input is passed in.  The return from this method is a collection of TokenResult instances.  These are all added to a collection.

 

var results = new List<TokenResult>();

            foreach (var token in Tokens)
            {
                results.AddRange(token.Parse(input));
            }

 

Organize

At this point, we have a collection of tokens that were identified.  They are in no particular order and order is going to be important to us when we start looking for a matching command definition.  So, all the tokens are organized into a dictionary of List<Token>.  The dictionary key is the start position of where the tokenized text was found in the input.  This way, we have an entry for each start position and a collection of Tokens that represent the particular piece of text found there.

 

var buckets = new Dictionary<int, List<TokenResult>>();

            foreach (var result in results.OrderBy(r => r.Start))
            {
                if (!buckets.ContainsKey(result.Start))
                {
                    buckets[result.Start] = new List<TokenResult>(); 
                }

                buckets[result.Start].Add(result);
            }

 

Evaluate

As I’ve alluded to many times, there are also method signatures defined to represent each command the systems knows about.  This methods might look like this:

 

public static void GetWeather(ConversationContext cContext, TokenList list, TokenWeather weather)
        {
            cContext.Say(WeatherService.GetTodaysWeather(cContext.ConversationUser), null);
        }

Each method defined for this purpose takes as its first parameter an instance of ConversationContext.  This object represents the conversation up to this point and allows a method to search back through the context to find things of interest.  For example, if I request a list of things from the system and it returns a list, I can add that list to the conversation context.  At some later time, if I ask the system to delete item number 4, how will the system know which item was number 4 unless it has access to the list that was returned before?  You might say that it could just re-retrieve the list, but what of the list of items has changed somehow?  If an item has been deleted from the list since it was returned last, number 4 might now be number three and the wrong item would be deleted. 

The context is also persisted in the database for durability.

The next two parameters are each tokens and we’ll try to match these with the tokens we have parsed out.

At startup, reflection is used to load all the methods into a collection.

 

var rules = new List<MethodInfo>();
           var assemblies = new List<Assembly>();
           var currentAssembly = Assembly.GetExecutingAssembly();
           string path = currentAssembly.Location;
           IEnumerable methods = null;

           foreach (string dll in Directory.GetFiles(Path.GetDirectoryName(path), "*.dll"))
           {
               try
               {
                   assemblies.Add(Assembly.LoadFile(dll));
               }
               catch (Exception)
               {
               }

           }

           foreach (var assembly in assemblies)
           {
               List<Type> ruleClasses = (from t in assembly.GetTypes()
                                         where !t.IsInterface
                                         where !t.IsAbstract
                                         where t.GetInterface("StructuredSpeech2.IRulesClass") != null
                                         select t).ToList();

               foreach (var ruleClass in ruleClasses)
               {
                   if (ruleClass == null)
                       continue;

                   methods = from m in ruleClass.GetMethods()
                             where m.IsStatic
                             select m;

                   rules.AddRange(methods.Cast<object>().Cast<MethodInfo>());
               }
           }

           return rules.ToList();

We look for any classes that implement the interface StructuredSpeech2.IRulesClass and then load all methods in these classes.

 

When input is received and after the Tokenization and organization steps, we loop through each of these methods.  For each, the parameters each expects are inspected.  The second parameter (remember the first is always our context) is compared with all the tokens found in the first list in the token dictionary to see if there is a match.  If so, the next parameter is compared with tokens in the second list and so on until all parameters have been inspected or we run out of either parameters or lists to compare.  For each method, we retain how many parameters match the tokens we have.

After all methods have been evaluated, we find the one method which matched on all parameters and that method is invoked via reflection.

 

Flexibility

I mentioned earlier that we could simulate synonyms by having our tokens pare out words with similar meaning in our context.  The other greatest point of flexibility is in how the command methods are defined.  Note that in the above example method that the two tokens in the definition were TokenList (which looks for “list”, “get” and “show”) and TokenWeather (which looks for “weather”).  The combination of the token definitions and the command definition allow any of the following to invoke the command.

list weather
list the weather (note that there is no token for “the” so it is effectively ignored
get weather
get the weather
show weather
show the weather

Posted in: .Net

Tags: , ,

View PDF files in Silverlight Applications

August 12, 2010 at 8:27 AMmgordon

I’ve amassed quite a collection of ebooks in PDF format and I recently had the idea to make them available from my server at home over the internet so I could access them from wherever I happened to be.  I wanted to write the application in Silverlight, but how to actually view the PDF’s?

The solution to this problem is possible because of the tight integration between Silverlight and the browser DOM.  Recall that if I enter the URL of a PDF document into the browser address bar, and I have a PDF viewer installed, an instance of the PDF viewer is created in the browser and it renders the PDF document.  We can use this behavior to render the PDF and make it look as though the PDF document is being viewed from the Silverlight application.

 

The HTML

Since we want to be able to leverage the browser’s HTML rendering behavior to show the PDF file, we need to create some HTML for the browser to render.  In the page that’s hosting the Silverlight application, create an iframe or div tag:

 

 

<iframe id="pdfFrame" style="visibility:hidden; position:absolute"><b>No Content</b></iframe>

 

 

Control Via Silverlight

No, in the Silverlight application, you need to create a control to “host” the IFrame.  You can’t actually insert the IFrame into the Silverlight visual tree, but we’re going to tie the IFrame and this control together in such a way that it looks like this control is hosted inside our application.  For our purposes, a grid will do nicely.

 

<Grid x:Name="LayoutRoot">
        <Grid.Background>
            <LinearGradientBrush EndPoint="1,0.5" StartPoint="0,0.5">
                <GradientStop Color="#FF101010" Offset="0.98299998044967651" />
                <GradientStop Color="Black" Offset="0" />
                <GradientStop Color="White" Offset="0.546999990940094" />
            </LinearGradientBrush>
        </Grid.Background>
        <Grid x:Name="pdfHost" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" 
              Margin="10" Background="White" LayoutUpdated="Grid_LayoutUpdated">
        </Grid>
    </Grid>

 

Notice that I’ve hooked the LayoutUpdated event.  In the handler for this event, we can tie the size and shape of our IFrame with that of the grid.

 

 

private void Grid_LayoutUpdated(object sender, EventArgs e)
       {
           ShowPreview();
       }
       private void ShowPreview()
       {
           GeneralTransform gt = pdfHost.TransformToVisual(Application.Current.RootVisual as UIElement);
           Point offset = gt.Transform(new Point(0, 0));  // Here you find your Panel Top/Left position
           int controlLeft = (int)offset.X;
           int controlTop = (int)offset.Y;
           HtmlElement m = HtmlPage.Document.GetElementById("pdfFrame");  // Find your HTML DIV
           if (m != null)
           {
               m.SetStyleAttribute("left", controlLeft.ToString() + "px");  // Set the Div position
               m.SetStyleAttribute("top", controlTop.ToString() + "px");
               m.SetStyleAttribute("visibility", "visible");
               m.SetStyleAttribute("height", pdfHost.ActualHeight.ToString() + "px");
               m.SetStyleAttribute("width", pdfHost.ActualWidth.ToString() + "px");
               m.SetStyleAttribute("z-index", "1000");
           }
       }

Here, you find the location of your grid and set the style of the IFrame to match its position and size.  In effect, every time the grid is resized or repositioned, the IFrame will follow it.  Notice how we use the HtmlPage class to access the host page’s DOM and find our IFrame.

 

Show the PDF

No that we have the IFrame tied to our grid, how do we actually show the PDF in the IFrame?

 

HtmlElement el = HtmlPage.Document.GetElementById("pdfFrame");
           el.SetProperty("src", "showpdf.aspx?key=" + key.ToString());

First, get a reference to the IFrame, again, and then set it’s src property.  Here, I have an aspx page that pulls the pdf file from another location and streams it to my IFrame.  If the PDF is located within your web directory structure, you can bypass the aspx page and just specify the path to you pdf file.

Posted in: Silverlight | ASP.Net | PDF

Tags: , ,

One MEF’ed Up App

May 24, 2010 at 8:13 AMmgordon

I’ve been working on a personal project and wanted to allow a plug-in architecture.  I have, in the past, written the code to dynamically discover assemblies in a particular location, load them and reflect on the types they contained to see if any implemented a certain interface I was looking for.  I have been hearing about MEF and decided to see if it offered anything by way of lessoning the pain of implementing plug-ins.

 

First, let me make it clear that the examples that follow work with the version of MEF installed with the Visual Studio 2010 release.  MEF is drop-dead easy to work with, but I did find it a bit frustrating to have to sift through examples I found on the web that no longer worked.  My recommendation is to look at the various tutorials available online to get an idea of what MEF is and what it’s designed to do.  However, trust only the MEF site on CodePlex for determining the exact syntax to use.

 

What I want from my application is to be able to drop assemblies that contain plug-in’s into a sub folder beneath my bin folder and have them be discovered and loaded into my application with minimal fuss and muss.  I created a class to manage all of this for me.  After setting a reference to System.ComponentModel.Composition, I created a collection property to contain all my plug-ins.

 

Import Collection
  1. [ImportMany]
  2. public IEnumerable<IExtension> Extensions { get; set; }

 

Each plug-in needs to implement the interface, IExtension.  I have added the [ImportMany] attribute to this property to tell MEF to add all classes that implement this interface to my collection.  Next, I created a class that implements the IExtension interface that I expect to be imported as a plug-in.

 

Plug-in class
  1. [Export(typeof(IExtension))]
  2.     public class STMWeather : ExtensionBase, IExtension

 

Here, I have created a class that implements IExtension and decorated it wth the [Export] attribute.  Since the class is not of type IExtension, I have to let MEF know to cast it as such before exporting, thus the parameter in the attribute.

 

At this point, I have a class to export and a property expecting to import, but how do I trigger the magic that pulls these two together?  Back in the ExtentionManager class (containing the property I’m importing into), I add the following code to the constructor.

 

Actual Composition
  1. public ExtensionManager()
  2. {
  3.     DirectoryCatalog catalog = null;
  4.     CompositionContainer container = null;
  5.     try
  6.     {
  7.         catalog = new DirectoryCatalog(@".\Extensions");
  8.         container = new CompositionContainer(catalog);
  9.         container.ComposeParts(this);
  10.     }
  11.     finally
  12.     {
  13.         catalog.Dispose();
  14.         container.Dispose();
  15.     }
  16. }

 

I create a catalog to contain all my plug-in’s and a container.  I think of the container as the witch’s caldron where the magic happens.  Next, I create the catalog by pointing it to the directory where my plug-ins live.  MEF will scan the folder and identify types matching what I’m expecting to import which are also decorated with the Export attribute.  Each of these will be added to the catalog.  Then, the container is created and it is passed the catalog.  Now, I make a call to ComposeParts and pass it an instance of the ExtensionManager.  This call tells MEF to use the catalog and try to satisfy any imports on the passed in instance with exports in the catalog.  When this call completes, my property will contain an instance of each plug-in found in my .\Extensions directory.

Having written the code to do all this manually, I can certainly appreciate the work that’s being done for me, here.  Very simple and very powerful.

Posted in: MEF

Tags:

Three Ways to Handle Silverlight Asynchronous Service Calls

March 16, 2010 at 8:48 AMmgordon

In Each of the examples, below, I’ll show the code that in the ViewModel and also in a service layer class that handles talking to the actual service.

One – Callback

public class ViewModel
{
    var _dataService = new DataService();

    private void GetData()
    {
        _dataService.GetCustomers(GetCustomersCallback);
    }

    private void GetCustomersCallback(object sender, GetCustomersCompletedEventArgs e)
    {
        Customers = e.Result;
    }
      
}

 

public class DataService
{
    var _client = new MyWCFServiceClient();

    public void GetCustomers(EventHandler<GetCustomersCompletedEventArgs> callback)
    {
        _client.GetCustomersCompleted += new EventHandler<GetCustomersCompletedEventArgs>(callback);
        _client.GetCustomersAsync();
    }
}

 

This approach really just extends the model that is generated in the proxy file for the service.  The ViewModel is called back on the callback method and the results of the call are available there for use.  To use a lambda expression and avoid having to write the separate callback method, you could do something like the below in the ViewModel.

 

public class ViewModel
{
    var _dataService = new DataService();

    private void GetData()
    {
        _dataService.GetCustomers( (o, e) =>
        {
            Customers = e.Result;
        });
    }
}

 

Two – Event

public class ViewModel
{
    var _service = new DataService();

    public ViewModel()
    {
        _service.CustomersLoaded += CustomerLoadCompleted;
    }

    private void CustomerLoadCompleted(object sender, ObservableCollection<Customer> customers)
    {
        Customers = customers;
    }
}

 

public class DataService
{
    var _client = new MyWCFServiceClient();

    public event EventHandler<<ObservableCollection<Customer>> CustomersLoaded;

    public DataService()
    {
        _client.GetCustomersCompleted += GetCustomersLoadedHandler;
    }

    void GetCustomersLoadedHandler(object sender, GetCustomersCompletedEventArgs e)
    {
        if (CustomersLoaded != null)
        {
            CustomersLoaded(sender, e.result);
        }
    }
    public void  GetCustomers()
    {
        _client.GetCustomers();
    }
}

 

Here, we let the data service raise an event to the ViewModel when the service call is completed.  This approach doesn’t gain us much unless there are multiple objects that need to be notified when the service call completes.

 

Three – Fake Synchronous Call

 

public class ViewModel
{
    var _service = new DataService();

    public ViewModel()
    {
        Customers = _service.GetCustomers();
    }

}

public ObservableCollection<Customer> GetCustomers()
{
    ObservableCollection<Customer> customers;

    _client.GetCustomersCompleted += (o, e) => 
    {
        customers = e.Result;
        re.set;
    }

    _client.GetCustomersAsync();
    re.WaitOne(1000);
    return customers;
}

 

So, here we’re using a ManualResetEvent to wait for the service call to complete.  We’ll wait for one second for the event to be set before we abandon the results and just return.  Use caution when using this approach as blocking a browser thread will totally freeze the UI.

Posted in: Silverlight

Tags:

The Value of Converters

December 1, 2009 at 5:55 AMmgordon

Over time, I’ve discovered more and more uses for value converters in my Silverlight and WPF applications.  In this post, we’ll look at what they are and some scenarios where they are useful.

What are value converters

If you’ve done any development in Silverlight or WPF, you know that when using these technologies, the user interface is specified in XAML, a dialect of XML.  Since we are using XML, or essentially strings, to defined our GUI the XAML parser needs to know how to turn the strings we specify into types.  For example, when we specify at attribute on a control such as IsEnabled=”True”, there needs to be away for the string “True” to be understood as a Boolean value.  When we say Background=”Black”, the string “Black” needs to be understood as Brush of color #FF000000. 

Both of these examples are common occurrences so there are built in converters that take care of these.  However, in our applications, there are likely going to be cases where we need to specify a value that the XAML parser has no idea how to interpret.  For these cases, we can create our own value converter to specify what type a string needs to be converted to.

An Example

Suppose you have a DataGrid in your UI that contains orders.  Each of these orders has a status property and you want to display an icon in each row that depicts the status of the order.  The grid is bound to a collection in the ViewModel.  How do you achieve this?

 

First, you’d need to define the column for the icon.  Perhaps, something like below.

<data:DataGridTemplateColumn Header="Status" CellTemplate="{StaticResource statusTemplate}" 
                                            IsReadOnly="True" Width="50" 
                                            CanUserSort="False"/>

 

Here, we specify the column’s layout in a template, statusTemplate.

<DataTemplate x:Key="stausTemplate">
    <Image Height="32" Width="32" Source="{Binding StatusCode, Converter={StaticResource statusToImage}, 
        Mode=OneWay}"/>
</DataTemplate>

 

In our template, we’re specifying an Image element, but binding its Source property to the status code.  Somehow, that status code has to be converted into a reference to an image file.  To handle that conversion, we specify a converter in our binding.  Let’s look at how to implement that converter.

To start, we need to create a new class and have it implement the interface IValueConverter.  Our class would look like this.

public class StatusToImageConverter : IValueConverter
    {

        #region IValueConverter Members

        public object Convert(object value, Type targetType, object parameter, 
            System.Globalization.CultureInfo culture)
        {
            throw new NotImplementedException();
        }

        public object ConvertBack(object value, Type targetType, object parameter, 
            System.Globalization.CultureInfo culture)
        {
            throw new NotImplementedException();
        }

        #endregion
    }

 

Implementing the IValueConverter interface requires us to implement two methods, Convert and ConvertBack.  The Convert method will be called to convert the original value to the desired value.  In our example, this method will be responsible for converting the status code to and image reference.  The ConvertBack method, does just the opposite.  If the converter is used in a TwoWay binding, the ConvertBack method will be called to convert a value specified back into a value of the original type.  In other words, if in our example the user were able to select an image, that image would be converted back into a status code before being pushed back into the order.

In our case, we’re only interested in using the converter in a OneWay binding, so we can leave the ConvertBack method un-implemented.  The finished class might look like the below.

public class StatusToImageConverter : IValueConverter
    {

        #region IValueConverter Members

        public object Convert(object value, Type targetType, object parameter, 
            System.Globalization.CultureInfo culture)
        {
            char statusCode = value.ToString()[0];

            switch (statusCode)
            {
                case 'A':
                    return "/Images/active.png";
                case 'W':
                    return "/images/working.png";
                case 'F':
                    return "/images/filled.png";
                case 'P':
                    return "/Images/paid.png";
            }

            return null;
        }

        public object ConvertBack(object value, Type targetType, object parameter, 
            System.Globalization.CultureInfo culture)
        {
            throw new NotImplementedException();
        }

        #endregion
    }

 

With the converter built, we just need to reference it in our XAML as a resource.

<converters:StatusToImageConverter x:Key="statusToImage"/>

 

Other Uses

What if in our grid, we also have a column that contains a dropdown containing the shipper that we will be using to ship our order.  The ItemsSource for the dropdown is bound to a collection of Shipper objects and its SelectedValue property is bound to a ShipperId.  That shipperId needs to be converted into a Shipper object in order for the binding to work.  Using what we know about value converters, we can create a converter that takes the id and looks up the corresponding object in a list.

Converters are incredibly flexible and powerful allowing you to inject logic into your UI easily.     

Posted in: Silverlight | WPF

Tags: ,

More about Silverlight RawFaults

July 31, 2009 at 3:32 PMmgordon

While writing the Silverlight applications at FunkyTools.com, I quickly found that not being able return exceptions from my WCF calls was a huge problem for me.  I located a solution that had been released by the Silverlight WCF team and, at the time, learned just enough about the code to get it integrated into my solution.  I documented how to use the code in a previous blog post. Recently, however, I’ve taken the time to dig into the code and learn more about how it works.

 

Why Faults Don’t Get Returned To Silverlight In The First Place

When Silverlight makes a WCF call, the communication with the server does not happen from the Silverlight application.  Rather, Silverlight uses the browser API to originate the call and the response comes back to the browser, first, and it passes it back to our application.  When an exception occurs in the WCF service, the return HTTP Response Code is changed from 200 to some other value to indicate the call was problematic.  If a response code other than 200 is returned to the browser, Silverlight gets handed back a “Not Found”" Exception from the browser and the actual exception information is lost.

 

The Sample Solution

The sample solution contains 4 projects.

  • SilverlightFaultBehavior – Defines a behavior that is added to a customer binding we can use to enable to have out exceptions returned.
  • SilverlightMessageInspector – Defines a new Channel and Binding for use in the solution.  This Project wires up the Channel, Binding,  and behavior.  These first two projects define all that’s needed to set up the server side of the functionality we desire.
  • SilverlightRawFaults – Defines a single class that is of interest which is a message inspector – more on this in a second.
  • SilverlightRawFaults.Web – A test web site to host the sample service.

 

SilverlightFaultBehavior Project

This project defines a single class, SilverlightFaultBehavior, which extends BehaviorExtensionElement and IEndPointBehavior.  Basically, it adds an additional behavior that we can tie to our bindings.  In this class, there is a method IDispatchMessageInspector.BeforeSendReply that contains the following code:

 

if (reply.IsFault)
{
   HttpResponseMessageProperty property = new HttpResponseMessageProperty();
   property.StatusCode = System.Net.HttpStatusCode.OK; // 200

   reply.Properties[HttpResponseMessageProperty.Name] = property;
}

 

So, basically, just before the response is returned to the browser, this behavior sets the return code to 200 if it’s any other value.

 

SilverlightMessageInspector Project

This project is basically a plumbing project.  It composes the behavior, channel and the message inspector into a binding, which when used, is pre-configured to return the exceptions we desire.

 

SilverlightRawFaults Project

This project contains file SilverlightFaultRawMessageInspector.cs and defines the two classes needed on the client side.  The file contains two classes; RawFaultException, a custom CommunicationException and SilverlightFaultMessageInspector which implements IClientMessageInspector.  In the latter of these classes a method, AfterReceiveReply, contains this code:

 

if (reply != null && reply.Version == MessageVersion.Soap11)
{
    if (reply.IsFault)
    {
        throw new RawFaultException(reply.GetReaderAtBodyContents());
    }
}

 

So, when the reply is received by Silverlight, but before it is returned to our application, this method checks to see if the reposonse contains a Soap 1.1 Fault and if it does, and instance of the custom CommunicationException is created that contains the fault details (error code, message and stack trace) and that exception instance is thrown into our application.

 

So, our response is inspected on the server and its response code is set back to 200 so the browser will interrupt the flow of our fault.  Once Silverlight gets the response, our client side message inspector checks to see if a fault is contained in the response and if so, the fault is converted into an exception and thrown back to the method in our application that originated the call.  

Posted in: .Net | Silverlight

Tags: ,

Coloring a ListBoxItem In Silverlight

July 6, 2009 at 10:47 AMmgordon

I was recently trying to display ListBoxItems with different colors based on criteria in the items the list was bound to.  More specifically, the challenge was not in changing the background colors, but with getting the color to fill the entire item.  After much searching, I found a blog post, here, by Ric Robinson that reminded me that I already knew how to fix the problem.

 

Why Setting HorizontalContentAlignment Doesn’t Work

As Ric explains, in the default ControlTemplate the alignment for the item is hard coded to “Left” which means that no matter what you do with the properties of the ListBox or ListBoxItem, the contents of the item will never stretch to fill the container.

 

The Solution

Since Silverlight allows you to override the style of any control, the solution is to create a style that is an exact copy of the default style and modify the HorizontalAlignment property to bind to the HorizontalContentAlignment value specified on the ListBox.  While I was at it, I modified several of the style attributes to suit my liking.

Posted in: Silverlight

Tags:

Funkytools.com is Live

June 28, 2009 at 10:18 AMmgordon

I’ve been working for months on a Silverlight application for task management that draws from the Getting Things Done philosophy among others.  I’ve created a web site to host the application at http://www.funkytools.com.  If you get the chance and are so inclined, check it out.

Posted in: General | Silverlight

Tags: ,