0 Comments
  •   Posted in: 
  • UWP

9f487017-1cc8-4ab2-88ec-eca71fab35c2[4]

In our last tutorial we created an UWP widget dashboard app (and platform) using Caliburn.Micro. The platform in its first version is very basic and we ended up listing many improvements to it:

  • Instead of always having all the widgets, user should be able to add and remove widgets.
  • Common widget elements, like title and action buttons.
  • Different sized widgets instead of a single fixed size.
  • Ability to send notifications from a widget to a widget using Event aggregator.
  • Ability to send notifications from a widget to the shell using Event aggregator.

In this tutorial we’re going to show how it’s possible to do widget to widget communication.

Background

We want our widgets to be self contained and isolated, meaning we don’t want them to interfere with the other widgets and we don’t want our shell to have to care about which widgets it is hosting.

Widgets can communicate with each directly and indirectly. Direct way (calling a method from another widget) introduces coupling and makes it harder to keep widgets isolated. Preferred way is to use indirect messaging.

Direct communication

It’s possible to communicate directly from a widget to an another but this isn’t recommended.If you really need to do this, a widget can reference other widgets through its Parent-property (which is provided by Caliburn.Micro). The following code shows how you can directly call methods from other hosted widgets:

            var widgets = ((ShellViewModel) this.Parent).Items;
            foreach (var widget in widgets)
            {
                if (widget is CustomerListViewModel customerList)
                {
                    customerList.AddNewCustomer(FirstName, LastName);
                }
            }

But as mentioned, you shouldn’t do this in most cases.

Indirect communication using the Event Aggregator

Caliburn.Micro contains an event aggregator. Event aggregator is a “middle man” which you can use to handle widget-to-widget, widget-to-shell and shell-to-widget communication.

With event aggregator your widgets (and shell) can raise messages. Any other widget can subscribe to the messages they are interested in. For example “NewCustomerWidget” can raise “NewCustomerAdded” message. “CustomerListWidget” can listen (to subscribe) to this message and react to it, by for example refreshing its view.

Given that we have NewCustomerWidget, it can can raise desired message using IEventAggregator.Publish(). First we need to define the message:

    public class NewCustomerCreated
    {
        public string FirstName { get;  }
        public string LastName { get; }

        public NewCustomerCreated(string firstName, string lastName)
        {
            FirstName = firstName;
            LastName = lastName;
        }
    }

Then we can raise (publish) the message from our widget:

    public class NewCustomerViewModel : Screen, IWidget
    {
        private string _lastName;
        private string _firstName;
        private readonly IEventAggregator _eventAggregator;

        public string FirstName
        {
            get { return _firstName; }
            set
            {
                _firstName = value;
                NotifyOfPropertyChange(() => FirstName);
                NotifyOfPropertyChange(() => CanSave);
            }
        }

        public string LastName  
        {
            get { return _lastName; }
            set
            {
                _lastName = value;
                NotifyOfPropertyChange(() => LastName);
                NotifyOfPropertyChange(() => CanSave);
            }
        }

        public bool CanSave
        {
            get
            {
                if (string.IsNullOrWhiteSpace(FirstName))
                    return false;
                if (string.IsNullOrWhiteSpace(LastName))
                    return false;

                return true;
            }
        }

        public NewCustomerViewModel(IEventAggregator eventAggregator)
        {
            this._eventAggregator = eventAggregator;
        }

        public void Save()
        {
            this._eventAggregator.PublishOnUIThread(new NewCustomerCreated(FirstName, LastName));
        }
    }

Main things to notice:

  • IEventAggregator is passed through constructor.
  • Message is raised using PublishOnUiThread.

Now that our widget can publish messages, we can add subscribers who can react to these messages. Here’s how we can make our “CustomerListWidget” to update its view anytime new customer is added:

    public class CustomerListViewModel : Conductor<Customer>.Collection.AllActive, IWidget, IHandle<NewCustomerCreated>
    {
        public CustomerListViewModel(IEventAggregator eventAggregator)
        {
            eventAggregator.Subscribe(this);

            this.Items.Add(new Customer("Test", "Customer"));
            this.Items.Add(new Customer("Another", "One"));
            this.Items.Add(new Customer("Mikael", "Koskinen"));
        }

        public void Handle(NewCustomerCreated message)
        {
            this.Items.Add(new Customer(message.FirstName, message.LastName));
        }
    }

Main things to notice:

  • IEventAggregator is passed through constructor and we subscribe our view model to it.
  • Our view model implements IHandle<NewCustomerCreated>

When we now run the app, we can see our two customer related widgets:

image

If we now create a new customer, we can see that the customer list is updated:

9f487017-1cc8-4ab2-88ec-eca71fab35c2

Conclusion

You can use direct widget-to-widget communication but instead you should prefer indirect messaging. Event aggregator makes it possible for widgets to publish and subscribe to messages.

The source code for this tutorial is available through GitHub.

0 Comments

imageIn this tutorial we will create an UWP Dashboard app. The dashboard will contain widgets where each widget is a self contained part, providing functionality to the app. We will be using Caliburn.Micro to build the app.

Background

We all have used widget based dashboard apps. VSTS’ project front page is just one example (you can see red arrows pointing to individual widgets):

image

Azure Portal is another good example:

image

Common for widget based dashboards is that each widget is a self contained part: It can work alone or with 1000 other widgets without interfering with the other widgets. Another common feature for widget based apps is the shell: Shell contains the common application UI (like the toolbar) and hosts the widgets.

Building widget based dashboard using UWP

We’re going to use couple libraries to build the dashboard: Caliburn.Micro is used to bring down the amount of code and Telerik’s UI for UWP is used for some pretty widgets. The Telerik’s UI components are great but in this case they are completely optional: You can create your widgets and the shell using any controls you want. But I would recommend using Caliburn.Micro as it allows to keep our code base simple and clean.

Caliburn.Micro

Caliburn.Micro is a MVVM framework. It is a convention based framework and after you learn the conventions, it is powerful and simple to use. The reason we’re using Caliburn.Micro in this app is its built-in view locator. The view locator is the component which allows you to easily build UWP dashboard apps and which allows us to do that with minimum amount of code.

Creating our app

We will start by creating the app and configuring Caliburn.Micro. Starting point is the “Blank App (Universal Windows)” template:

image

Target and minimum versions don’t really matter:

image

MainPage.xaml can be deleted at this point.

To hook up Caliburn.Micro, first add the Nuget package “Caliburn.Micro” (version 3.2):

image

Then open App.xaml and change it into the following format:

<cm:CaliburnApplication
x:Class="UWP_WidgetDasboard.App"    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:cm="using:Caliburn.Micro"
    RequestedTheme="Light">

</cm:CaliburnApplication>

All the App.xaml.cs requires few changes: It doesn’t inherit Application anymore so we can remove that and also some Caliburn.Micro specific setup is needed. Once you get this right, you can usually just copy paste the code from app to app. The full App.xaml.cs can be found from this tutorial’s GitHub repository but here’s the most interesting parts:

        protected override void Configure()
        {
            container = new WinRTContainer();
            container.RegisterWinRTServices();

            container.Singleton<ShellViewModel>();
        }

        protected override void OnLaunched(LaunchActivatedEventArgs args)
        {
            if (args.PreviousExecutionState == ApplicationExecutionState.Running)
                return;

            DisplayRootView<ShellView>();
        }

Configure-method will be used to initialize the widgets and the shell. OnLaunched decides page is shown at launch. As we can see the code uses ShellViewModel and ShellView so let’s create those before we can hit F5 to make sure everything works.

ShellView is just a blank page:

image

And ShellViewModel is a class which inherits Screen:

using Caliburn.Micro;

namespace UWP_WidgetDasboard
{
    public class ShellViewModel : Screen
    {
    }
}
Now if you hit F5 you should see our empty app starting without errors:

image

At this point we have a working app with a shell but without any content. The solution explorer is the following (highlighted are the files which we have changed):

image

Next up is creating the widgets.

Creating the first widget

For each widget we need two things:

  • UserControl for the UI
  • Caliburn.Micro based ViewModel (Screen or Conductor) for the logic

We also have to have a common IWidget interface, which can be empty. This is our starting point:

namespace UWP_WidgetDasboard
{
    public interface IWidget
    {
    }
}

Let’s create our first widget: Customer Info. To get some structure, we’re going to create a folder for each widget. These aren’t required but they make things easier to find. Create an empty user control (CustomerInfoView) and an empty class (CustomerInfoViewModel) into the project:

image

CustomerInfoViewModel is the place where widget’s logic will be: It can contact the database/web api to fetch data or access some resource packaged with the app. The CustomerInfoViewModel should be a “Caliburn.Micro ViewModel”, meaning it needs to inherits from a Screen or from a Conductor. Screen is your choice if you want to display information about a single object, Conductor is great if you have a list of object. For example CustomerInfoViewModel is a Screen because we just display info about a single Customer. CustomerSearchViewModel should be a Conductor as it quite likely displays a range of customers.

To make things work, the widget’s view model should also implement our IWidget interface. When using Caliburn.Micro, the widget’s initialization logic can be placed inside the OnActivate-method. Let’s insert some logic:

    public class CustomerInfoViewModel : Screen, IWidget
    {
        private Customer _customer;

        public Customer Customer
        {
            get { return _customer; }
            set
            {
                _customer = value;
                NotifyOfPropertyChange(() => Customer);
            }
        }

        protected override void OnActivate()
        {
            this.Customer = new Customer("Mikael", "Koskinen");
        }
    }

    public class Customer
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }

        public Customer(string firstName, string lastName)
        {
            FirstName = firstName;
            LastName = lastName;
        }
    }

Now we just implement the UI for our widget to display customer information:

    <Grid>
    
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition/>
            <RowDefinition/>
        </Grid.RowDefinitions>

        <TextBlock Style="{StaticResource TitleTextBlockStyle}" Grid.ColumnSpan="2" Text="Customer Information:"/>
        <TextBlock Style="{StaticResource SubtitleTextBlockStyle}" Grid.Column="0" Grid.Row="1">First name:</TextBlock>
        <TextBlock Style="{StaticResource SubtitleTextBlockStyle}" Grid.Column="0" Grid.Row="2">Last name:</TextBlock>

        <TextBlock Style="{StaticResource BodyTextBlockStyle}" Grid.Column="1" Grid.Row="1" Text="{Binding Customer.FirstName}"/>
        <TextBlock Style="{StaticResource BodyTextBlockStyle}" Grid.Column="1" Grid.Row="2" Text="{Binding Customer.LastName}"/>

    </Grid>

Next up is making the shell work.

Creating the shell

The shell hosts the widgets and the common UI functions. We’re going the skip the common UI functions and just include a container which contains all the widgets.

The shell is where you decide how you want to represent the widgets: You can use similar square box containers as VSTS’ or you can host each widget in a tab control or hub or carousel or anything you like. We’re going to use the square box containers.

All the widgets are “injected” into the ShellViewModel using dependency injection. This way shell doesn’t need to know which widgets it is currently hosting.

To get the dependency injection working, we need to add all the classes implementing IWidget into the Caliburn.Micro’s DI container. This is done in App.xaml.cs:

        protected override void Configure()
        {
            container = new WinRTContainer();
            container.RegisterWinRTServices();

            container.Singleton<ShellViewModel>();
            AddWidgets();
        }

        private void AddWidgets()
        {
            var types = typeof(ShellViewModel).GetTypeInfo().Assembly.GetTypes().ToList();
            var widgets = types.Where(type => type.GetTypeInfo().IsClass && System.Reflection.TypeExtensions.IsAssignableFrom(typeof(IWidget), type)).ToList();

            foreach (var widget in widgets)
            {
                container.RegisterPerRequest(typeof(IWidget), null, widget);
            }
        }

Now when we run the app, all the widgets implementing IWidget are automatically added inside the DI container. We can use this in our ShellViewModel. At this point we should also change ShellViewModel to inherit Conductor<IWidget>. This provides us Items-property, which we can use to add the widgets:

    public class ShellViewModel : Conductor<IWidget>.Collection.AllActive
    {
        public ShellViewModel(IEnumerable<IWidget> widgets)
        {
            this.Items.AddRange(widgets);
        }
    }

Now we have the basic logic implemented and we just need to display the widgets inside the ShellView. For this you can use any container. We’re going to use ItemsControl with ItemsWrapGrid:

    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <ItemsControl x:Name="Items">
            <ItemsControl.ItemsPanel>
                <ItemsPanelTemplate>
                    <ItemsWrapGrid Orientation="Horizontal"/>
                </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <Border BorderThickness="2" BorderBrush="LightBlue" Margin="12" Width="400" Height="400">
                        <Grid>
                            <Border Background="LightBlue" Opacity="0.1"/>
                            <ContentControl Margin="12" micro:View.Model="{Binding}" HorizontalContentAlignment="Stretch" VerticalContentAlignment="Stretch" />
                        </Grid>
                    </Border>
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>
    </Grid>

Now when you run the application, you should see our single widget hosted inside the shell:

image

We can make sure everything works correctly by adding couple more widgets:

image

image

Conclusion and further work:

This tutorial shows what it takes to create UWP dashboard widget app. It doesn’t take much: Only few lines of code is required to for the shell and IWidget, after which all the coding takes place inside the widgets. As each widget can be as complicated or as simple as they need, bulk of your code will be place into the individual widgets.

To make this full blown solution, the widget system needs some more functionality:

  • Instead of always having all the widgets, user should be able to add and remove widgets.
  • Common widget elements, like title and action buttons.
  • Different sized widgets instead of a single fixed size.
  • Ability to send notifications from a widget to a widget using Event aggregator.
  • Ability to send notifications from a widget to the shell using Event aggregator.

The full source code can be found from the GitHub: https://github.com/mikoskinen/blog/tree/master/UWP-WidgetDasboard

0 Comments

Azure ARM templates allow you to automate your environment setups. But with a cost. Dealing with the long JSON-files is hard, even though there are visualizers like ARMVIZ available.

What can we do? In this series I’ll explore the options for automating your Azure environment setup.

Background

If you can create a completely new and fresh Azure environment for your system with a click of button, with everything deployed automatically, you’re in the happy land. If you can’t and setting up the environment requires some manual work, you should aim to automate the process completely. If you run the automated process twice, we want to end up with two identical systems but with the following differences: Each installation should have their own passwords and own urls.

ARM in Azure’s context stands for Azure Resource Manager. The key scenarios for ARM, as defined in the documentation, are:

  • Deploy resources together and easily repeat deployment tasks
  • Categorise resources to clarify billing and management
  • Enable enterprise-grade access control

We’re mainly interested in the first key scenario: How to automate your deployment.

When we use ARM, we’re using JSON based ARM-templates. We deploy the JSON-file, which Azure Resource Manager then converts to REST calls and the REST calls create the required resources. The key thing is that we only have to care about our JSON-template, ARM takes care of the rest.

Problem

ARM templates are great because they allow you to automate the environment setup. But they come with a cost: ARM templates tend to grow to these huge, almost monstorous JSON-files which are hard to understand and to maintain. And as we know, maintanability is the key when we want our systems to have a long life.

GitHub has a great source for templates. You can create simple and complex environments with these templates, ranging from something simple as Windows VM to MongoDB high availability installation. But if you look at these templates you can easily see the problem: the simple Windows VM is 179 lines of JSON. MongoDB is 500 lines.

Personally I think that the problem with ARM templates is obvious: The templates try to use JSON in a situation where it isn’t build for. In theory you can use JSON to describe your environment. But to actually make things work you need some concepts from programming languages:

  • Variables
  • Conditions
  • Loops

XML and JSON are both great ways to describe static data but they fall short when you try to “programming languagefy” them. ARM templates aren’t the only one with the same problem: If you check the JSON-file behind the Azure Logic App, you usually find a mess. If you try to use text editor for editing a Mule ESB flow, you will encounter problems.

Options

Given that the aim of an automated environment setup is great but ARM templates are hard to maintain, what can we do? I personally believe that instead of trying to make JSON to act like a programming language, we should use an actual programming language.

So instead of using an ARM template to describe your environment, you create a C# console application to describe and to create your environment using Azure Management Libraries for .NET.

Or if your environment is simple, you can use .bat-files (Azure CLI) or Powershell scripts (Azure Powershell) to automate your environment setup.

Conclusion

This post was aimed to give you the background. In the following posts I will explore and compare three options for automating your Azure environment setup:

  • ARM templates
  • Azure Management Libraries for .NET
  • Azure CLI

0 Comments

This post shows how to use Azure Service Bus Topics and filters to handle a scenario where events and event handers aren’t known when starting the system.

Background

One of our systems can contain 0 or 10 different event types. And it can contain 0 or 100 event handlers. The idea is that the event handlers can be added dynamically runtime. And to make things even more interesting, also the events can be added runtime. One event can have zero-n event handlers.

We use Azure Service Bus topics for the pub&sub model of communication.

The problem

The problem is that if we don’t know the types of events when starting the system, how can we easily create the required topics?

The solution

The solution was to only use one pre-defined topic and then to filter the communications using Azure Service Bus subscription filters.

More details

As the events and event handlers can change dynamically when the system is running, pre-creating all the Service Bus topics is cumbersome and not actually possible. To get around this there’s couple options:

  1. The event creator and event handler both try to create the Service Bus Topic if it doesn’t exists.
  2. All the event creators and handlers use the same pre-created topic and use message properties and subscription filters to handle only the relevant messages.

We ended up using the second option. So there’s only one topic (system-events) and all the event creators push their messages into the same topic.

When pushing the event, the event creator adds a property to message which defined the message’s type. For example newinvoice.

All the event handlers then subscribe to the same system-eventstopic. But when creating the subscription, they attach a filter to the subscription, indicating what types of messages they are interested in.

How to use the topic filters in C#

The official Azure GitHub contains a good sample of using Service Bus topic filters in C#.

Main thing is to specify the filter on event handler when creating the subscription:

  await namespaceManager.CreateSubscriptionAsync(
        "system-events",
        "newinvoicesubs"
        new SqlFilter("eventtype = 'newinvoice'));

Other thing to remember is to define the event type when pushing to the topic:

var message = new BrokeredMessage();
message.Properties = {{ "eventtype", "newinvoice" }};
await topicClient.SendAsync(message);

0 Comments

In this post we will use NetMQ to build a solution where multiple clients can run commands on the server and the server dynamically created a worker for each command.

Background

ZeroMQ and its .NET port NetMQ are interesting technologies. They seem to have a rather smallish but very enthusiastic group of users and the “scene” gives similar vibes as the Redis community.

ZeroMQ is a technology for adding distributed messaging into your system. Pub & sub, reply & request and other types of communication patterns are available. ZeroMQ doesn’t require a server installation, so it’s a library instead of full blown server solution. For communication, you can use TCP, inproc and other techniques.

Dynamic workers

We needed to use NetMQ in a situation where there’s multiple clients running commands on the server. The idea was that the server would spin up a worker for each client request. Even though ZeroMQ’s documentation is good, finding an example with dynamic workers turned out cumbersome.

We ended up using the following topology:

Client: RequestSocket

Server: RouterSocket (TCP 5555) – DealerSocket (TCP 5556) & Poller

Worker: DealerSocket

Creating the server

The server has a frontend for the requests coming from the client. It also has the backend for communicating with the workers. Poller is used to handle the messages:

Console.WriteLine("Starting server");
using (var front = new RouterSocket())
using (var back = new DealerSocket())
{
    front.Bind("tcp://localhost:5555");
    back.Bind("tcp://localhost:5556");

    var poller = new NetMQPoller();
    poller.Add(front);
    poller.Add(back);

	front.ReceiveReady += (sender, eventArgs) => {...};
	back.ReceiveReady += (sender, eventArgs) => {...};

	poller.Run();
}

Creating the workers

When the server’s frontend receives a message, we want to spin up a new worker. In this example we use ThreadPool to create the worker:

front.ReceiveReady += (sender, eventArgs) =>
{
    var mqMessage = eventArgs.Socket.ReceiveMultipartMessage(3);

    var id = mqMessage.First;
    var content = mqMessage[2].ConvertToString();

    Console.WriteLine("Front received " + content);

    ThreadPool.QueueUserWorkItem(context =>
    {
		// The worker
		// Parameters are available from the context.
        var context = (Tuple<NetMQFrame, string>) context;

        var clientId = context.Item1;
        var message = context.Item2;

		// Run the command
        Thread.Sleep(TimeSpan.FromSeconds(3));

		// Send message to server's backend which then will return the reply to the client
        using (var workerConnection = new DealerSocket())
        {
            workerConnection.Connect("tcp://localhost:5556");

            var messageToClient = new NetMQMessage();
            messageToClient.Append(clientId);
            messageToClient.AppendEmptyFrame();
            messageToClient.Append("hello from worker");

            workerConnection.SendMultipartMessage(messageToClient);
        }

    }, Tuple.Create(id, content));
};

Returning the message to client

As we can see from the code above, the worker message sends the reply to the server’s backend. Only thing left is to route the reply back to the client:

                    back.ReceiveReady += (sender, eventArgs) =>
                    {
                        Console.WriteLine("Back received message, route to client");
                        var mqMessage = eventArgs.Socket.ReceiveMultipartMessage();
                        front.SendMultipartMessage(mqMessage);
                    };

The client

Our client uses RequestSocket to call the server’s frontend. We use a blocking call, so we wait for the server (the worker) to reply:

using (var client = new RequestSocket())
{
    client.Connect("tcp://localhost:5555");
    client.SendFrame("hello from client");
    var returned = client.ReceiveFrameString();
    Console.WriteLine(i1.ToString() + ": back at client " + returned);
}

Conclusion

This post shows one solution for spinning up worker tasks (threads) dynamically using NetMQ. Even though NetMQ only includes few basic concepts, the concepts are so flexible that it’s quite that there’s many other ways to handle this situation.