This post started from the thought of pulling user profile information from GitHub and showing it in the form of a GitHub card. Since I could not find any such examples, I thought why not we create an example here at alternatestack.com.
Actually GitHub has long thought about this already. It has provided APIs to interact with GitHub. There is also a C# port of the GitHub API. It was earlier available as GitHub.Sharp. The same API has been moved and renamed to Octokit. There is also a reactive version of Octokit. This is Octokit.Reactive package. The dependencies of the package can be visualized as follows:
These APIs can request information from GitHub in authenticated and non-authenticated modes. But there is a limitation of number of un-authenticated client requests per hour. So it is better to make authenticated client requests.
If you would first start going through the API, you would see a lot of XClient types. Nearly all of them are inherited from ApiClient type. If we create a class diagram of these types, then a very inheritance hierarchy seems to emerge. This might make you a little confusing for just pulling user profile information.
Let’s first create a simple type to support change notification support for our model and view model. It just implements INotifyPropertyChanged interface and provides definition of the required event to support change notification. The interesting point is to use Expression for this purpose. This would enable us to avoid magic string and a compile time check to support change notifications for these types.
Now let us see how we can download a user’s information from GitHub. Here we have already added Octokit nuget package. The model has required properties to hold user information. Now take a look at method DownloadUserInformationAsync. This is an async method. It uses GitHubClient to download a client’s information. Since a user can make any number of requests in an hour, we are creating authenticated requests. The caller is supposed to pass the credentials as arguments. Here we have to await on user information and his repositories’ details. Fortunately Octokit provides async method for both of them. After getting the information, we are just assigning them to the model’s properties.
Now we need to define view model for GitHubCard. It has similar properties as the above model. It uses the model to load a client’s information using async / await. Now we can assign these properties to view model’s ones. This is a perfect place to exploit Automapper. You can add it as nuget package to your project. First we need to create mapping between properties of two types, then we can create a new object from an existing object of the source type. We can also assign values to properties of an existing object based on source type. This is exactly what we are doing here. Since view model already exists, we are just assigning values to its properties using model’s properties.
In the above code, we are calling an async method from constructor. Here we cannot use await with this call as we would need to declare our constructor as async, which is neither allowed nor it makes any sense. Although the code is legal for compiler and would seem to work but it looks like a bad practice. Here we are returning the object (it is constructor after all) even before the object’s state is completely loaded. What if the caller now uses a property which we haven’t initialized yet? How would a caller make sure that the object is completely initialized??
To counter-argue, we can say that this not a regular object but it’s a view model which implements INotifyPropertyChanged. Here we don’t need to initialize the view model object completely but we want to show the view to the user. As object state is loaded, we would be assigning values to the properties. Since it implements INotifyPropertyChanged interface with property change notifications, the view would be reflected with the view model’s state.
I know you don’t like this. So let’s try to see what we can do. Just to make it more fun, Microsoft didn’t have any support for behaviors in .net for Windows Store Apps. Luckily, they have recently provided an extension SDK for supporting behaviors. This is available for Windows 8.1 projects on Visual Studio 2013. You would still need to add the reference using Reference Manager as follows:
This would appear as follows in the project’s references:
Now we can get rid of the call of the method from view model’s constructor. Instead we can introduce an ICommand property with async execute method to call the method used to load user information. Since we don’t have a default implementation of ICommand, we have added Prism’s nuget package for Windows Store Apps.
Now we can use this view model as the DataContext for our view. Here we are using interaction behavior available from the behavior SDK. We can invoke a command using InvokeCommandAction . Here we are using Loaded event in EventTriggerBehavior for this purpose. The rest is regular XAML where elements are data-bound to properties in the view model. Alternatively, we could use Prim’s ViewModel type which has built-in support for OnNavigatedTo / OnNavigatedFrom but let’s keep that discussion for a later day.
Now let’s run the application. We see the following view on display.
Just to recap on the nuget packages, we have used Octokit.net provided by GitHub. In addition we have used AutoMapper and Prism for Windows Store Apps.