SlideShare ist ein Scribd-Unternehmen logo
1 von 33
Downloaden Sie, um offline zu lesen
INTERACTIVE
APPLICATIONS IN .NET
Master of Software Engineering
AUTHOR
ANDREI FANGLI
SCIENTIFIC COORDINATOR
DR. IOAN LAZĂR
JUNE 2016
"BABEȘ-BOLYAI" UNIVERSITY, FACULTY OF MATHEMATICS AND COMPUTER SCIENCE
Interactive Applications in .NET - Table of Contents
Table of Contents
1. Applications Today................................................................................................................................................3
2. Asynchronous Programming.............................................................................................................................5
3. Architectural Approach..................................................................................................................................... 11
3.1. Model-View-ViewModel......................................................................................................................... 14
3.2. Defining the Context: Observable Domain Objects ..................................................................... 15
3.3. Asynchronous Model ............................................................................................................................... 17
3.4. Validation...................................................................................................................................................... 20
3.5. Visual State Manager ............................................................................................................................... 23
4. Implementing the Machine............................................................................................................................. 25
4.1. Reactive Extensions................................................................................................................................... 31
5. Conclusions........................................................................................................................................................... 32
6. References ............................................................................................................................................................. 33
Interactive Applications in .NET - Applications Today
3
1. Applications Today
A few years back, the number of applications available to the general public was rather small
compared to their number today. Most of them were huge, enterprise level, applications that serve
the needs of a company, after all, who is paying for all that effort? Developing software was harder,
resources were limited and sometimes difficult to come by even though the Internet was generally
available.
As years went by and developer tools got rich and richer, more people jumped on the boat of
software development. Creating software is still hard, but not as hard as it was 10 years ago.
Making a desktop application by one self is a tiring effort as it requires a lot of features to even
compete with the software already available. Not to mention user interaction.
When tablets and smartphones came out, it was a first sign that there will be a boom in the
numbers of developers. Once Software Development Kits came available for creating applications
for various mobile platforms the trigger was pulled, and the explosion happened. There are
literally tons of mobile applications. Anyone with little knowledge about writing code can
download one of these Software Developments Kits and are already writing their application.
Having virtual stores, in contrast to classic desktop applications, for mobile applications is a bonus
as it offers a degree of security, a user is not going to any site to download free software, it is the
official store for a mobile platform. Nothing should get in there without proper verification.
These stores do not require from the application that is being published to be complex, in fact
any simple application can make its way to the store without much problem. There are some that
simply keep the score for a game of cards, some that just store one list where a user can only add
and remove items to it.
Tablets and smartphones are not meant for heavy duty computations; they are accessories that
fit in pockets or really small bags. They are meant to be useful in most if not all situations. Some
people spent some of their time with their friends playing card games, how useful it is having the
phone keep the score rather than memorizing it? How useful is it to have a “to-do” list on a phone
than instead of a piece of paper for which one also needs a pen to be able to write on?
Tablets and smartphones have a lot of small and simple applications. This is the perfect
environment for a single person to write an application that ends up being used by a lot of people.
Tools available today make it really easy to write such applications, there are hundreds of libraries
available that help in solving specific problems, there are a lot of Q&A sites, blogs and books that
can aid just about anyone to create their own application. [1]
This boom in software developers is both beneficial and somewhat damaging. Besides the risk to
security as scam applications that somehow get past store verification and get published there is
also the risk of bad software. Not as in ill-intended applications that drain battery or do some
other damaging action on purpose. It is easy to write bad code, too easy. One can write all their
Interactive Applications in .NET - Applications Today
4
logic in the code-behind of a page without using a single await statement. Besides having a bulk
of non-reusable code that cannot be even tested automatically, it does not have a rich user
experience. The user needs to wait for the application to finish whatever it is processing, or rather
wait until the web service the mobile application has invoked returns as the phone itself should
not do any heavy duty operations. [1]
Applications today must be responsive! The user is in charge of their phone, not the other way
around. Any mobile application that is not responsive sits on the same shelf with broken
applications. The developer must take into consideration that at any point in time there may be
an incoming call or the user simply needs to do something else with their phone. At any point in
time the application must be ready to respond to what the user wants.
Practically, it is impossible to respond in the exact same instant, it may be damaging to do so as
an interrupt right in the middle of a write operation could corrupt the file that is being saved. [2]
On the other hand, everything is from the perspective of the user. A small delay since the user has
tapped the cancel button until it actually happens is acceptable. It is difficult, if not impossible, for
a human being to tell whether the device responded exactly when the button was tapped or a few
hundred milliseconds later.
In order to be able to handle multiple events, or at least apparently handle them, one needs to
consider parallel programming or asynchronous programming. Parallel programming comes with
its own trouble of synchronization and multiple worker threads, joining threads and so on.
Asynchronous programming, on the other hand, may be the best fit for allowing developers to
create rich user interfaces.
Asynchronous programming does not necessarily mean to move all computation on a separate
thread so the user interface thread is free to receive other events and interact with the user. If
small chunks of code are executed in a sequence in such a way that a tap event or an income
phone call may come between them and eventually changing how the remaining chunks of code
in the sequence are executed, then it is possible to give the impression that the application is
doing multiple things in parallel when in fact it is doing little bits of more things giving the
impression of parallel execution. [2]
As long as there is visual feedback and the users are free to interact with the application and with
their phone they will not tell the difference. Probably they do not even care about what is beneath
the interface as long as the application does the job. One way to make rich user interfaces and
responsive applications without all the synchronization issues that parallel programming may
bring is through the use of asynchronous programming.
Interactive Applications in .NET - Asynchronous Programming
5
2. Asynchronous Programming
In conventional programming, in order to stop a long running method from blocking the caller of
that method one would create a new thread and have it execute the long running method. One
issue with this approach is signaling when the operation has completed in order to make
necessary user interface updates, but also make use of the result of the operation. [2]
In asynchronous programming, parallelism does not happen outside of the operation, but rather
inside. Parallelism is initiated inside the long running method only if it is necessary. [2]
This promotes encapsulation since there is no need to know whether a method is long running or
not in order to use a separate thread. If the user interface freezes because a method takes too
much time to complete, the optimization happens within the method. Responsibility falls on the
implementer to refine their code, not on the user.
There is still the issue of signaling completion. Whenever an operation completes, regardless of
whether it is synchronous or asynchronous, it is a must to have some way of knowing when it
completed.
Typically, asynchronous methods do not block the caller. They return control to them before doing
any actual work. In order to either know when the operation completed or have a continuation to
that operation, asynchronous methods either return an object that can be used in that way or take
a callback that will be called when the operation completes. [2]
The initial approach in .NET was to use callbacks for continuations. Operations that could be
executed asynchronously, such as reading from a stream, have a BeginX/EndX pair of methods for
the corresponding X method, which was synchronous. For instance, the asynchronous pair of
methods for Read are BeginRead/EndRead. BeginRead would take a callback, among other
parameters that are also available for the synchronous Read version, that was executed once the
operation has completed. The method returned an object implementing IAsyncResult that has to
be used as parameter when calling EndRead. [2]
In some cases, it would be possible to have the callback executed right away since most, if not all,
stream implementations use a buffer behind the scenes. If the buffer already had the necessary
data that was requested for an asynchronous read, the callback would have been invoked right
away with the result. On the other hand, if the buffer did not already have the necessary
information, it would load into the buffer on a different thread and only afterwards it would invoke
the callback.
This is one of the advantages of asynchronous programming, sometimes the code is not executed
on a different thread because it is not always necessary. Forcing parallel execution by moving the
actual method invocation to a different thread cannot yield such advantages unless the entire
method is decoupled.
Interactive Applications in .NET - Asynchronous Programming
6
One of the issues with the callback approach is that it promotes unreadable code that is also hard
to maintain or extend. For instance, asynchronously making a request to a web service will require
a callback for continuation. If the call is successful, responds with HTTP status code 201 - Created,
then another call needs to be made to a different web service. The second call happens insides
the callback. If the second request fails, responds with HTTP status code 400 – Bad request, then
the first request to the web service needs to be undone which will turn out to be another
asynchronous call, with another callback.
How would this be written in a synchronous fashion? Make the first request, if the response has
status code 201 then proceed with second request, if that is unsuccessful then undo the first one.
The code ends up really easy to read even if the actual requests are not extracted into separate
methods.
How would the code change when another web service needs to be called when the undo fails?
For the asynchronous approach it would mean another callback, while for the synchronous
approach is just another if with another line of code. Easy to test, easy to extend.
In .NET callbacks are provided through parameters of delegate type. Parameters of this type, or
event handlers, accept anonymous methods or lambda expression. As with functional
programming, when using lambda expressions, one can create closures over certain objects thus
when passing a callback to a BeginX method, one can use a lambda expression, instead of an
ordinary method, and inside it to close some of the variables. This is extremely useful, but it also
blocks any kind of method extraction from the callback unless code is made less readable. [2]
There is no doubt that the callback approach has its benefits, most notably the fact that there is
no need for an actual signaling mechanism as it is certain that the callback is executed only after
the asynchronous operation has completed. However, this approach promotes code that is hard
to read, hard to maintain. [2]
The issue of handling exceptions does not need exemplification. The try… catch statement already
makes code less friendly to eyes, but the real problem is resource management.
With the callback approach one needs to manually dispose the resources they use since the using
statement does not split into lambda expressions. Resources need to be created outside of the
callback and disposed when they are no longer necessary, no matter what! This is a critical as an
exception can be thrown either when calling the BeginX method, either in the callback if the
asynchronous operation fails. Resource disposal needs to happen in either case! [2]
Resources that require manual handling implement the IDisposable interface. Usually these types
also define a finalizer to ensure that the resource is safely deallocated even when Dispose is not
called. Relying on the finalizer to actually deallocate resources yields memory issues as the
Common Language Runtime has a generational garbage collection system. Objects that will have
their finalizers invoked will be promoted to at least generation 1, if the next garbage collection
does not include generation 1 then these objects will get promoted to generation 2! To actually
Interactive Applications in .NET - Asynchronous Programming
7
reclaim the memory occupied by generation 2 objects the entire memory used by the application
needs to be cleaned. [2]
Exception management is a big problem alongside readability with the callback approach.
There are more issues with this approach, however it is clear that writing code having this in mind
is not exactly that easy and there are too many things that could go wrong, now there are
alternatives to this approach which solve most of the problems.
Tasks symbolize a unit of work that may not have completed but can be used to either block until
it has completed, enlist continuations for when the operation has completed thus blocking is
avoided but the callback issue returns or await them in C# asynchronous methods. [2]
Tasks were introduced in .NET 4; they represent an abstract concept that enables high level parallel
programming. Threads are primitive structures on which other parallel concepts are built on, they
do not easily enable fine-grained parallelism. It is difficult to compose little parallel operations
using threads in contrast to Tasks. A Task is literally a delegate that gets executed on one thread
or another depending on the task scheduler. [2]
Tasks can be easily composed using operations such as WhenAll or WhenAny as the result of
either of these methods is another Task. It is easy to write code that executes in parallel that at
some point some operations need to wait on each other to complete before the overall operation
can continue. [2]
Since C# 5.0, the language has support for asynchronous programming. Developers are no longer
required to make a big effort into writing asynchronous code. The async and await keywords have
been introduced, any method decorated with async must either return a Task or void. The await
keyword can be used on methods that return a Task. [2]
One of the great advantages of async and wait is that it enables developers to write code that
looks like synchronous code, but in fact it is asynchronous. All of the actual splitting and plumbing
is done by the compiler behind the scenes. [2]
Having language support is very important as it is a standard approach to this style of
programming in the respective language, but also makes these concepts generally available
directly in the language rather than some third party library. Plus, it is far less likely to have bugs
in what the compiler translates than a third library would.
Back to the web services example. Writing code synchronously it would look something like the
snippet bellow:
if (Request1().StatusCode == 201)
if (Request2().Failed)
UndoRequest1();
Interactive Applications in .NET - Asynchronous Programming
8
Really simple, however to invoke web services requires a number of steps that could take enough
to make a user interface freeze. First is the DNS1
lookup, then it’s the actual connection, serializing
the request and sending it over Internet. Afterwards the service processes the request and
responds.
It is possible that the service invoked to take a bit to load, or the web host is too busy processing
other requests and our request would eventually end up in a timeout. This is one example where
code should be written in an asynchronously in an effort to keep the user interface responsive.
Using the async and await is really simple and straight forward:
if ((await Request1Async()).StatusCode == 201)
if ((await Request2Async()).Failed)
await UndoRequest1Async();
It does not seem to have changed much, however there are more implications than what it may
seem.
When the compiler encounters an await it splits the method in two. From a high point of view,
everything before the await is extracted into one method and everything after it goes to another
method. To make the link between the two, the compiler uses the awaiter that is returned by
calling GetAwaiter on a Task to subscribe a continuation. When the awaited operation completes
then the continuation will be executed which will contain the remainder of the asynchronous
operation. [2]
The method transformation that the compiler applies to an async decorated method do not
change much from the initial approach with callbacks, the great advantage is that the compiler is
generating the necessary callbacks rather than the developer. This reduces the likely hood of
introducing bugs and also enable some of the code C# features, such as conditionals, loops, try..
catch and using statements. [2]
Since the method is split into multiple, there is the problem of maintaining method state. Variables
and parameters that were either defined or provided inside an asynchronous method must be
available throughout the method regardless of whether the compiler decides to split the method.
Besides just splitting the asynchronous method after await statements, the compiler actually
transforms each async decorated method into a state machine. Parameters and variables are
stored as the context of the state machine which is encapsulated inside an object of type Task
which is returned by the async decorated method. When then asynchronous method completes
then the returned task transitions to either RanToCompletion, Faulted or Canceled states. [2]
Since the transformations done to an async method are somewhat similar to what a developer
would write using the callback approach, one needs to ask. Where does the code actually execute?
1
DNS stands for Domain Name System. The overall principle of the system is to associate names to IP
addresses so it would be easier for human beings to memorize the location of a web site.
Interactive Applications in .NET - Asynchronous Programming
9
Is it a thread from the thread pool? Is it always a new thread created by the task scheduler? Where
does code actually execute? This is an important issue because all graphical user interfaces that
can be written with .NET (Windows Forms, Windows Presentation Foundation) or WindowsRT have
a dedicated thread (UI Thread), for interacting with any user interface components. Changes to
the user interface and events from their controls are all executed on the UI Thread, any attempt
to change the user interface from a different thread ends with an exception. [2]
The way most user interfaces work is that they implement a producer-consumer pattern where
the consumer is the UI Thread and a producer can be anything. A click on a button, an event from
the operating system and so on. As events happen, their handlers, which are nothing else than
callbacks, are posted in an execution queue where they may be prioritized. The UI Thread is
constantly inspecting this queue and when an item is available it removes it from the queue it and
executes in on the UI Thread. [2]
All tasks are scheduled by a task scheduler which behind the scenes uses a Synchronization Context
to actually marshal the code. When a task is awaited, the awaiter actually captures the current
Synchronization Context to subscribe the remained of the method. [2]
If necessary, one can implement their own Synchronization Context and have full control over how
tasks are actually executed. Each thread can have at most one Synchronization Context set, if there
is none set then the default is used which actually relies on the thread pool to carry out the actual
execution. [2]
All graphical user interfaces that can be programmed through .NET or WindowsRT set a specialized
Synchronization Context for the UI Thread. The respective instance can be obtained and passed
down to view models, controllers or other types of objects as a means to marshal code unto the
UI Thread. It is already known that this is how async and await does it. [2]
Whenever an async method is awaited whose execution was initiated on the UI Thread, usually
the click event handler of a button or within the Execute method for a command to which a button
is bound to, the continuation is posted to the specialized Synchronization Context which relies on
the UI Thread to carry our actual execution. Eventually, continuations end up on the UI Thread and
the user interface can be safely updated. [2]
Writing responsive user interfaces means to have visual feedback for whatever the user does or
for whatever event happens under the hood. If a long running operation is started, it may entirely
run on the UI thread, but that does not necessarily mean waiting for the long operation to finish
until any event is handled.
The beauty of asynchronous programming in C# is that async methods are actually fragmented
into smaller pieces where each is scheduled one at a time. This fragmentation allows for other
events to be pushed unto the UI Thread execution queue in between the smaller pieces and
respond accordingly to those events and in time.
Interactive Applications in .NET - Asynchronous Programming
10
One can carry out all their work on the UI Thread alone. If the code is written well it may seem to
the user that the application actually runs multiple jobs in parallel. In truth it does not execute
anything in parallel, it just does one little bit of multiple tasks at a time.
Regardless of whether there is some real parallelism behind, the user interface stays responsive.
The user can constantly interact with the application and based on its current state it may be able
to carry out some operations and not others.
While it all may seem fine with asynchronous methods in C#, there are a few subtle side effects
that async methods have. [3]
One of them are the fake awaits. It is possible for an async method to actually complete
synchronously and return an already completed task. For instance, the snippet bellow relies on a
cache to fetch data faster: [3]
public async Task<string> GetMessageAsync()
{
if (IsMessageCached())
return messageFromCache;
var message = await someService.GetANewMessageAsync();
Cache(message);
return message;
}
If the message is cached, then it is fetched from there and the async method completes
synchronously. On the other hand, if this is the first time the method is called, it is most likely that
the message is not cached, thus the call to GetANewMessageAsync is made. Depending on what
happens inside the awaited method the GetMessageAsync may return with a Task that is not yet
completed. The same principle is applied recursively. [3]
An async method will return prior to actually finishing when it will find a real await. These happen
when a task that executes on a different thread is actually returned or when a call to Task.Yield()
is awaited. The latter does nothing special. It simply forces the compiler to actually split the
method in two having the side effect of having the async method actually return control to the
caller when the call to Task.Yield() is made. This is a safe way of ensuring that the async method
will always return control to the caller before it actually finishes. [2]
One last topic to cover when it comes to asynchronous programming is cancellation. Like in most
other platforms, cancellation is signaled. The operation that is being canceled has to check, from
time to time, whether a cancellation has been signaled. [2]
Cancellation is requested to a task through a CancellationToken. One can use
CancellationTokenSource which exposes a token that can be passed to one or more tasks. To signal
a cancellation request one must call the Cancel method on the CancellationTokenSource which in
turn will mark the token with cancellation requested. [2]
Interactive Applications in .NET - Architectural Approach
11
3. Architectural Approach
While asynchronous programming can be beneficial to writing interactive applications, they are
only part of the solution. In order to have a rich user interface it must also be updated constantly
to show both available options depending on what the application is doing at that point, but also
what information is available and whether new information is being retrieved from somewhere.
Things such as progress bars, fade and other kind of animations make the user experience more
pleasing, if a list of items just pops up without a smooth fade in animation the application will
seem less user friendly.
Starting with Windows Presentation Foundation and now also in WindowsRT, one can make use of
the already available tools to write rich user interface applications. Controls already come with
their own bag of animations which make the application pleasing, since they are out of the box it
is likely to encounter the same animation as other applications and even what the operating
system is using. This helps with the look and feel as just navigating through such an application
will already make it familiar and inviting. [4]
One critical part to writing good applications is how they are structured. For quite some time, user
interfaces build with Visual Studio, either Windows Presentation Foundation for Windows Desktop,
or WindowsRT for mobile platforms, use XAML to describe them. [4]
XAML stands for eXtensible Application Markup Language, it is a derivative of XML2
and enables
developers to create user interfaces, and not only, in a declarative meaner. Every XAML file is
bound to a concrete class, the code within that class is referred to as code-behind. [4]
Clearly, C# code will not go into the XAML file. On the other hand, in the code-behind class one
can access anything that was defined in the corresponding XAML file. This is one of the reasons
why the code-behind exists, to cover for anything that cannot be made through XAML, such as
enabling or disabling buttons based on some event, handling button clicks and so on.
This is where asynchronous programming comes into play. One can write an asynchronous event
handler for handling what happens when, for instance, the user fills a form and clicks the save
button. Right when the event handler starts, the button is available in the code behind and thus
it can be disabled during the save operation. The save operation itself is asynchronous thus it is
awaited, there is no telling how long it will take but during that time the button is disabled. When
the save operation completes the button is enabled and the user is free to add another item.
If the handler were to be synchronous, there would be no need to disable and enable the save
button, but because of the compiler fragments the async methods, it is possible that the user to
click the save button while the operation is being carried out and have the event handler executed
once again before the first call is finished (see figure 1).
2
XML stands for eXtensible Markup Language. It was first introduced to help transfer data between
applications.
Interactive Applications in .NET - Architectural Approach
12
FIGURE 1: SYNCHRONOUS VS ASYNCHRONOUS EVENT HANDLERS
Synchronous
UI Thread
1st
button click
<<event handler>>
SaveButton_Click
2nd
button click
<<event handler>>
SaveButton_Click
Asynchronous
UI Thread
1st
button click
<<event handler>>
SaveButton_Click
2nd
button click
<<event handler>>
SaveButton_Click
The synchronous way is simple and straight forward, however it may lead the user interface to
freeze which leads to a very poor user experience. The asynchronous way illustrates both a
problem and a feature.
As it can be seen in figure 1, using asynchronous event handlers may lead to overlapping
execution. It is possible to have multiple handlers in progress at the same, clearly it could lead to
some problems if a user is allowed to save the same entity twice at the same time. Because of this,
as previously mentioned, the developer must take extra steps in the code behind to ensure that
the save button is unavailable while the associated action is being executed.
On the other hand, other buttons may become available. For instance, while the application is
saving an entity it could be possible to cancel that operation. Having a synchronous approach,
clearly that cannot happen as easily as it can with an asynchronous approach. Imagine that instead
of the second button click it would be a cancel button click event. That would signal the save
operation to cancel which may either lead to actually cancelling the operation, or the cancellation
to fail. It is possible that the user to click right the cancel button right when the entity was saved,
thus canceling the operation means actually deleting the entity.
Working with the code-behind is just one, less promoted way, to respond to events. XAML
encourages binding controls to various properties in order to both provide data to them but also
respond to events such as button clicks. [4]
Interactive Applications in .NET - Architectural Approach
13
Data binding encourages separation of concerns, usually an object providing data and commands
through properties is used as a binding source for a view. The binding source can raise specific
events in order to inform the user interface to update itself. [4]
The data source to which a control binds to may expose a number of properties, this is usually the
case, which themselves become binding sources.
Observer is a behavioral design pattern implies that an object, referred to as the subject, maintains
a list of different objects, whose concrete type is unknown, referred to as observers. Whenever the
subject changes it is responsible with notifying all observers about that change. [5]
In .NET, the observer pattern is implemented using events which themselves are implemented
using delegates. A delegate is a reference to a function. Through a delegate one can invoke a
method that an object exposes, or not, as well as a static method. [2]
It is possible to have an event handler, which is basically a method subscribed to an event, that is
actually a private method. Events in .NET do not require the observer to implement any specific
interface but rather have either a method with a specific signature or an adapter for it. Anonymous
methods or lambda expressions can be used to subscribe to a method and actually have them
call a private method of an object. The lambda expression is actually a closure around the instance
whose method will be called. [2]
User interface controls, not just Windows Presentation Foundation and WindowsRT ones, Windows
Forms as well, rely on INotifyPropertyChanged interface in order to be notified whether the binding
source has changed. It is not mandatory to implement this interface, an object that does not
implement it can still be bound to, but the respective control will not receive update notifications
and thus it will not update. [4]
INotifyPropertyChanged exposes just one event, PropertyChanged which relies on the
PropertyChangedEventHandler delegate. Most event handlers require a method with two
parameters, an object which refers to the initiator of the event, the subject and an instance of
EventArgs or one of its derivatives. In this case, when the event is raised a specialized EventArgs is
sent which informs which property has changed through its PropertyName property. [4]
Besides binding to data, views can also bind to commands. Command is a behavioral design
pattern in which an object encapsulates the invocation to an operation. [5]
In order to successfully bind to a command, a binding source needs to implement the ICommand
interface. This interface exposes two operations, CanExecute(object) and Execute(object) alongside
an event, CanExecuteChanged. [4]
Basically, the object implementing this interface needs to be both a command and a subject. This
is done in order to avoid pooling the CanExecute(object) method, when there is a chance that the
result of the respective method to have changed, the CanExecuteChanged event is raised. This will
Interactive Applications in .NET - Architectural Approach
14
make controls call CanExecute(object). Based on the result, the button becomes available or
disabled. When a user clicks on a button, the Execute(object) method is called.
The object parameter which is required by both methods is a value that can be optionally specified
when binding to a command. This is useful for commands like navigating to a page. It page
number itself does not have to be encapsulated inside the command object, but can be provided
as a parameter. However useful, any change on the command parameter that is signaled to the
user interface through the PropertyChanged event will not initiate a call to CanExecute(object)!
3.1.Model-View-ViewModel
Separating views from business logic enhances code reusability but also testability. It is easy to
test whether an object has the desired behavior when it can be passed input that would normally
come from the user and see what it outputs.
For application where the user interaction needs to be rich, there is need for an intermediary layer
between the view and the business layer in order to properly handle the logic behind a view. [6]
The Model-View-ViewModel is an architectural pattern focusing on separating the view and its
logic from the business models of the application in an effort to separate concerns and thus obtain
more granular, maintainable, testable and reusable code. [4]
All data is provided to the view by the view model and all requests from the user are forwarded to
the view model. The view model itself relies on a model, which can be a data model or any business
object, to retrieve data and operate on (see Figure 2).
FIGURE 2: MODEL-VIEW-VIEWMODEL OVERVIEW
ViewModel
<<binding>> <<property changed notifications>>
Model
View
<<provides data>><<changes>>
In this case, the view model is the binding source of the view. It provides both data and commands.
This can lead to a lot of code duplication, for every model there should be a view model or
something similar, as well as ending up with classes having multiple responsibilities. There are
exceptions to the Single Responsibility Principal, but data and behavior should not be mixed
together in the same class. [7]
Interactive Applications in .NET - Architectural Approach
15
3.2.Defining the Context: Observable Domain Objects
In Domain Driven Design, it is proposed to model the business layer around the domain for which
the application is being implemented. While doing this, the model should be constantly presented
and approved by domain experts in an effort to reduce the risk of misunderstanding and also help
create a ubiquitous language. [8]
There is more to Domain Driven Design than the above paragraph, but this paper focuses on
describing an approach towards creating interactive applications in a clean and reliable way. This
has an impact towards how certain concepts in Domain Driven Design are affected.
The domain layer should contain only classes that are either entities, values or domain services.
Entities are objects that have a thread of life in some way. For instance, in an application which
manages movies, it is important that when a user is reading about a movie to be the same movie
that the administrator introduced. Usually when changing one of the properties of an entity, it is
not a new entity but the same one. [8]
Value objects, on the other hand, are simple values. For instance, the length of a movie is a value
as it is not important whether the value is created each time a movie is being loaded from the
database or not. It can be stored as the number of minutes the movie lasts and when it is retrieved
from the database a TimeSpan is created from that value. The difference between a value and an
entity is that values should be immutable, when one wants to change a property of a value or the
value itself, it is a new value rather than the same one with an update. [8]
So far only data structures have been covered. There are more complex applications in which the
software must perform an action that is domain specific. One of the most common examples is
changing the currency of a sum. Accountants have a formula for how to transfer a sum from one
currency to another besides the currency transfer rate and the source sum. It is likely that after a
transfer the resulting sum needs to be rounded. The entire logic of transferring a sum from one
currency to another is implemented in a domain service since these actually model operations on
data rather than data itself. [8]
Going strict by definitions, it would mean to have a number of types that model the domain in
the business logic layer. A number of view models, a considerable part of them will map one-to-
one with domain objects, that expose both data and behavior through commands for a view to
bind to. Last but not least, a number of repositories for managing entities in a storage.
The mapping between the business model and their respective view models can be done through
an Anticorruption Layer [8]. But what would the view model wrapping the domain object do
anyway? It would only expose the same properties as the model does only that the view model is
observable. This is a direct violation of Don’t Repeat Yourself principle.
Besides duplicating code, there is also the issue of circular references. The domain model is
implemented however the business demands, if it demands circular references then there will be
such associations. When working with references, which is mostly the case in .NET and other
Interactive Applications in .NET - Architectural Approach
16
platforms, one must think of the relationships between objects as a graph, for what it truly is, and
not as a tree, which is only a subset of all possible cases.
How would the Anticorruption Layer fair with circular references? Extra checks would need to be
set in place in order to avoid infinite loops or StackOverflowExceptions. That means a greater
performance cost, more time spent until actual data is shown on the user interface. Writing view
models for each domain model by hand rather than have a tool to generate them means more
time spent by a developer on less engaging matters. Creating a tool to generate view models
would seem like an appropriate challenge for a developer, but either approach needs to deal with
the circular reference issue. Some sort of cache needs to be implemented in order to properly
map the domain object graph to the view model object graph. [9]
Last but not least, one could write a generic class that wraps an object and through reflection it
automatically generates other view models for the wrapped object with a few exceptions such as
strings, integers and other data types considered to be primitives. This approach eliminates
intellisense completely as properties are implicit, not explicitly defined on the view model class.
Any approach taken either increases development costs or end up in eliminating very useful
features offered by the integrated development environment. The price needs to match the reward
or this is a very bad deal.
What if, the domain objects were themselves observable? What if, one could bind directly to them
without any intermediary? If there is any circular reference between them, it is already set when it
gets to the view. There is not duplicate code and there is no time wasted in doing so.
In order to be able to bind to an object and automatically have the user interface updated when
one of their properties change one must only implement INotifyPropertyChanged which exposes
only one event. The entire subscriber list is managed by the delegate which is used to implement
the event. All that is required is to raise the respective event when a property is being set.
This is a very small price to pay when implementing domain entities and values for what is
obtained in return. To ease development, one can offer a base implementation of
INotifyPropertyChanged and simply derive all observable objects from there. The base
implementation would provide a protected method for raising the respective event taking a string
parameter which will resemble the property name that has changed.
Interactive Applications in .NET - Architectural Approach
17
3.3.Asynchronous Model
When domain objects become observable one can easily bind the user interface controls to them.
Even view models themselves can subscribe to their events in order to carry out different
operations. For instance, when the property of an entity changes it would be required to validate
the updated entity. If there are any errors an observable collection of errors would be updated
and thus any control that has bound to it will automatically display them.
All user interface controls rely on objects that implement INotifyPropertyChanged and
INotifyCollectionChanged interfaces to update themselves. They both only expose events for
notifying when the subject has changed. Both the ObservableCollection<T> and
ReadOnlyObservableCollection<T> are types present in .NET framework that implement these
interfaces and they should be used to speed development. [4]
One important aspect of software development besides data is behavior. Software is mostly about
behavior; it is mostly about doing something over a dataset.
Interactive application demand that the user has constant visual feedback, even when the
application is busy carrying out a request, there is a progress ring or something that informs the
user that something is going on and may have some progress updates.
When a user navigates to a view where they can edit an entity, typically, it means that a form is
displayed with a number of input controls, when the user hits save there is a validation of the data
that has been introduced. If the data is valid then the entity is saved, otherwise a list of error is
shown. The user experience is poor in this case. Whenever a user wants to see whether their input
is valid, they need to click on save.
From a behavioral point of view, the view is going through several states. It starts off in the editing
state where the user is free to provide input. When the save button is clicked, the view actually
first transitions into a validating state and depending on the outcome of the validation it either
transitions into a saving state or transitions to an invalid state.
If the application were to be implemented synchronously, which offers a lesser user experience,
all these states are implicit and the view does not require any kind of modeling since the sequence
of transitions is quite simple with two possible outcomes.
On the other hand, if the application is written using asynchronous programming in an effort to
provide a rich user experience, then having an implicit state machine may prove confusing and
less maintainable. After a developer would investigate a bit the view, it would most likely become
clear that there is a state machine at play even though it is implicit. [10]
As the view transitions from one state to another the user interface needs to update. Some actions
can be performed while in a state but cannot be performed while in another. [10]
It is clear that there is need to model the state machine behind a view, but how does it fit with the
View-Model-ViewModel pattern? The data has already been isolated from view models, leaving
Interactive Applications in .NET - Architectural Approach
18
them open only to resembling behavior. Where better place would there be to implement a state
machine? After all they are used to model behavior in software systems. [11]
A Mealy Machine is a finite-state machine that uses both its input and its current state to determine
its output. They can be used to model asynchronous reactive processes and, as with most if not
all finite state machine models, it focuses on observable inputs and outputs. [12]
In case of a view model which is an implementation of a Mealy Machine, further referred to as an
interactive view model, operates based on a context which resembles the input and sometimes
even the output as properties of an object may be set by the view model. [12]
Depending on its current state and context, the interactive view model may transition to one state
or another. If, for instance, the operation that is being carried out is a save operation then the
output of the machine is the successful storage of the entity. [12]
Commands that are exposed by an interactive view model can be bound to states that it defines.
When an interactive view model transitions from one state to another, the commands it exposes
automatically update. In other words, they raise the CanExecuteChanged event which in turn will
make the control that has bound to the respective command call CanExecute(object) method. The
method itself encapsulates the logic for verifying whether the command is bound to the current
state of the interactive view model or not.
An interactive view model should always expose a state, even if it is a state that is used to expose
that behind the scenes, an operation is actually performed. When an operation finishes,
depending on what requests have been received in the meantime and the context of the machine,
the interactive view model will make another transition.
It becomes obvious that states can be grouped into two main categories. Action states and quiet
states. Actions states are states in which the interactive view model is carrying out a request. It is
executing an asynchronous operation.
Quiet states, on the other hand, are the typical states in which the interactive view model exposes
some commands that are available to the user. In these states, the application is quietly waiting
for user input.
Initially, an interactive view model can be in either an action state or a quiet state, but whenever it
enters an action state it should eventually transition to a quiet state unless an endless loop of
operations is carried out. This is just a guide line, there are exceptions.
For instance, a pooling loop can be implemented using action states. There is a pooling state in
which information is being fetched and presented to the user, and afterwards there is a waiting
state. The interactive view model will stay in the waiting state for a fixed period of time and
afterwards will transition back into the pooling state. The waiting state it actually is an
asynchronous operation that is implemented using Task.Delay(int) or Task.Delay(TimeSpan).
Interactive Applications in .NET - Architectural Approach
19
Even though it may seem simple, one must take into account that it is possible that the fetch to
fail due to losing Internet connection or a timeout on the other end. For situations such as these,
the application can have a number of attempts to fetching data. If they all fail, then the interactive
view model should transition to a quiet state where the user is asked for further instructions.
If action states perform that actual operation, then what would a command really do? This is really
simple. The commands that are exposed by an interactive view model actually resemble transition
triggers for the view model that exposes them. Furthermore, the command can be bound to
specific interactive view model states which will make them available based on the current state
of the interactive view model that exposes them.
When a command is invoked it will actually trigger a transition inside the interactive view model
which in turn will update other commands and also start the desired operation. Any button that
was bound to a command exposed by the same interactive view model will get an update. The
will become available or disabled with respect to the current state of the interactive view model.
Another issue, which was previously raised, is overlapping asynchronous operations. If a command
is actually a transition trigger, then what would happen if the interactive view model is currently
in an action state and a command that triggers a transition is invoked? Regardless of what initiates
the transition, whilst in an action state, an interactive view model cannot transition to any other
state. Any attempt to do so will result in an InvalidOperationException. The interactive view model
can carry out one operation at the time, this does not block signaling cancellations and it does
not block making changes to its context. When the context has changes, the interactive view
model must react accordingly.
Blocking transition requests while in an action state, in certain situations, forces the developer to
find a work around this restriction that would only end up in code duplication. For instance, when
the interactive view model is in the validating state and a change to its context occurs by user
interaction, the interactive view model should automatically cancel the validation and start over
as the data is currently validating is already outdated.
To answer to this strictness, the interactive view model allows queuing transition requests. When
a transition is queued the interactive view model will perform the transition if it is in a quiet state,
if not then it will transition as soon as it enters a quiet state.
The queueing mechanism resolves the validation problem, and probably others as well. If the
interactive view model is already validating, then queueing another transition to the validating
state seems appropriate as the same operation needs to be carried out all over again.
Since action states resemble actual operations, it does not make sense to have an external event
dictate how many times the interactive view model needs to queue state transitions. The response
to the event is that the interactive view model will transition to the desired state at some point in
the future if not immediately. If a request to queue a transition matches the last in the queue, then
Interactive Applications in .NET - Architectural Approach
20
it is ignored. By this, if there are multiple changes to the context, thus multiple transition queue
requests, there will only be at most one queued transition request towards the validating state.
Clarifying thus far, the initial approach towards Model-View-ViewModel was to have a view model
that provides properties for both data and commands that a view could bind to. In an effort to
decrease costs and make code more reusable, the view models no longer expose data directly
through its properties, but rather expose a context property which refers to an actual domain
object. The view model implements a Mealy state machine behind the scenes in an effort to model
its behavior in an explicit and clean way. Commands exposed by the interactive view model are
actually triggers to transitioning to one state or another. These triggers can also queue transitions.
3.4.Validation
Thus far only data and behavior has been covered. One important thing within software
applications is validation. Validation is the act through which a set of data is checked in order to
determine whether it conforms to a number of rules.
Validation can be of multiple forms such as user input validation, schema validation, whether a
product meets the requirements of a user and so on.
Previously it was presented that domain objects should contain only data and that they should
also be observable so they could be used directly by a view in an effort to avoid duplicate code
and reduce the responsibilities of a view model. Continuing with the same idea, where should
validation take place? More specifically, where should user input validation take place.
A common way used through web applications built with ASP.NET MVC is to annotate models
with various attributes, such as RequiredAttribute or EmailAddressAttribute which can be used to
validate an e-mail address, that specify what kind of validation should be carried out on them.
In case the attributes do not suffice, one can always implement ValidationAttribute and perform
any custom validation that is required for a property, in case there is a requirement for which
multiple properties must be involved or the value of one property determines the validity of
another then one must implement IValidatableObject interface and provide custom validation in
the implementation.
This approach eliminates any layer dedicated for validation, however it imposes that the model
itself should validate itself or at least specify what makes it valid. Both validation and data
representation fall unto one class. [6]
Besides, the same models can be used with an Object-Relational Mapping framework, such as
Entity Framework, in an effort to simplify queries and data storage. The same class may end up
being responsible for representing data, validating that data at a given point in time and also
specify how it is stored in a relational data base. [9]
As previously said, validation is of multiple kinds and they are treated differently. For instance,
user input validation is a kind of validation that results in collection of error messages, preferably
Interactive Applications in .NET - Architectural Approach
21
localized so they can be displayed in multiple languages, which is then displayed to the user.
Schema validation where a given object is stored to a data store, any store not just relational, does
not return a collection of error but throws exceptions. If a given object does not conform to the
database schema, then there is most likely a programmatic error. Throwing an exception is the
reasonable thing to do as it signals an abnormal situation.
Constraints come from multiple sides, domain constraints are set by domain experts which also
have a big part to play in developing the domain model. [8]
There are also schema constraints, such as how many characters can a string contain, whether a
field is an integer or a real number, a Boolean value and so on. Schema constraints are only set at
the storage level, they may bring some restrictions to the domain model itself and the two may
also overlap. When the two do not overlap it is better to bring domain constraints into the schema
constraints only if they do not impact performance.
Having this in mind, it is time to reflect this on the design thus far. Moving validation outside of
the model itself means that there is a new component having this responsibility. The view model
cannot be used to also contain domain validation as it is already responsible with managing a
state machine. [11]
The validation component will be responsible with validating a given domain object and providing
a list of errors where the error message is preferably localizable. This increases reusability as the
same type of object can be validated from multiple perspectives. There can be multiple validators
that validate the same kind of object but having different logic encapsulated within them.
Through this approach the domain objects can be used, as they are, by repositories. When
retrieving an object from a repository one can always execute the validator in an effort to ensure
that whatever the repository retrieved is valid from the point of view of the domain.
Besides, data representation is separated from its validation. It is true that there is a dependency
relation from the latter towards the former, however having them separated increases testability.
One can write unit tests just for domain validation logic without having to change the domain
model representation.
Wrapping it up, after analyzing a few alternatives that seem to be paying off the initial Model-
View-ViewModel approach has changed slightly (see figure 3).
Interactive Applications in .NET - Architectural Approach
22
FIGURE 3 DECOUPLED MODEL-VIEW-VIEWMODEL
ViewModel
<<binding>>
<<property changed notifications>>
Model
View
<<provides data>>
<<changes>>
<<property changed notifications>>
Validator <<validates>>
<<uses>>
<<binding>>
Clearly, there are more dependencies this way, however the initial approach did not take into
account multiple aspects of an application.
There are two binding sources now for the view, the view model and the model itself. The former
provides commands, which encapsulate behavior, to the view while the latter provides data to the
view. In case of the model, there is also the possibility of two-way binding as user input needs to
make its way to the model so it can be validated.
Notice that there is no association between the view and the validator. It falls under the
responsibility of the view model to validate the model; however, this behavior is delegated to a
validator class which provides the view model with a collection of errors. The view model simply
exposes this collection as an observable one thus the view will be automatically notified when it
changes. Validation should be triggered automatically when a change to the model is made, such
changes mainly happen through user interaction as the model is mainly updated through a two-
way binding.
Thus far, the overall architectural approach is decoupled, behavior is separated from data
structures. The classes representing data may be reusable as they only provide a number of
properties with specific data types and nothing else. Validation logic is testable and any change
in the respective logic does not affect the domain model, unless the latter was designed wrong in
the first place.
The view model represents a state machine containing quiet and action states. Commands, which
are provided by the view model, are bound to specific states making the available in some states
and not in others. The view automatically enables and disables buttons based on the availability
of the command they are bound to. [11]
Interactive Applications in .NET - Architectural Approach
23
3.5.Visual State Manager
So far, the only user interface interaction that was presented was enabling and disabling buttons
through a command. That is hardly an interactive application as there is a lot more to this kind of
applications than buttons.
On the other hand, the part that was presented thus far is critical to a functioning application.
Besides having a rich user interface, it is important to have functional software and most
importantly to be able to write it with ease and at speed.
Rich user interfaces have nice animations; controls update their visual aspect depending on what
the application is doing in the back or whether the device on which the application runs is turned
or moved.
Animations have been a difficult thing to do since there is not always support from the underlying
framework for them. Starting with XAML this has changed. Both Windows Presentation Foundation
and WindowsRT have built-in support for animations and even offer a handful of predefined
animations for the developer to use.
A control may define for itself and contained controls a number of visual states. Each visual state
is contained in a visual state group. A control may be in at most one visual state in each group.
This means that the control may be in multiple visual states at the same time, but only at most
one per visual state group.
For instance, a number of controls define a visual state group for the orientation of the device. For
each possible orientation, landscape or portrait, the visual state group contains visual states. When
the user rotates the device, the visual state is updated and thus the visual aspect of the control is
updated. Depending on the type of control they may display more information, or they may just
expand to fit the available space after it was updated through the device rotation.
Each visual state contains a set of instructions on how the control should transition to the
respective visual state. It contains a declarative description for animations. Start values may be
specified, but if omitted the current values of the respective property are used. This is useful as
this allows the visual state to practically be able to transition smoothly from any other visual state.
If, for instance in the middle of an animation another visual state transition is triggered, then the
currently executing animation is stopped and the one specified by the latest visual state transition
is started. Since start values can be omitted, the animation can still execute smoothly without
having controls having sudden visual changes which are unpleasing.
The entire visual state definition and transition is done through the Visual State Manager. This
class is responsible for housing visual states for each control and making visual state transitions
available to the developer in code-behind.
Since the view model transitions from one state to another depending on what it is
asynchronously doing behind the scenes, the view needs to update itself the same way. The view
Interactive Applications in .NET - Architectural Approach
24
model is always in a state, there is no such thing as “transitioning”. The view model exposes its
current state through a State property. Whenever the state changes a PropertyChanged event is
fired by the view model so the view is notified of the changed.
For each view model state, the view may define for itself visual states. When the view model
changes its state, the view will transition to the visual state having the same name. Visual states
contain specifications for how the control, or contained controls, should animate for this change.
This makes them perfect for adjusting any visual aspect to illustrate that the application is working
behind the scenes.
Besides having buttons enable and disable when a view model transitions from one state to
another, the view can now properly adapt to this change and update any control on the interface
to illustrate the change.
For instance, when the view model transitions to the saving state, the view may fade out all user
input controls and fade in a process ring which shows that the application is currently saving the
entity. When the view model completes the save, it will transition to the editing state while the
view will fade out the process ring as the application is no longer processing and fade back in the
user input controls.
Figure 4 illustrates a simple interaction using a sequence diagram. [13]
FIGURE 4 SIMPLE INTERACTION
:UI saveCommand :TriggerCommand :EntityViewModel :Repository
Execute(null)
TransitionToAsync("Saving")
<<event>>PropertyChanged("State")
SaveAsync(entity)
<<event>>PropertyChanged("State")
<<tap>>
save
<<visual state transition>>
<<visual state transition>>
Interactive Applications in .NET - Implementing the Machine
25
4. Implementing the Machine
Thus far there was mostly, if not only, design ideas. How would the ideas presented previously
would actually be implemented? Is it even feasible?
Starting with one of the most critical parts of the library, implementing INotifyPropertyChanged.
Binding relies on it in order to update the content of a control. Since the interface only exposes
one event, PropertyChanged, it is relatively easy to provide a default implementation.
One of the goals of the default implementation is to simplify how the event is raised. As with
all .NET events, raising one requires to invoke the backing delegate of the event with both the
initiator of the event, referred to as sender, and an EventArgs, or one of its derivatives.
For the PropertyChanged event the argument is represented by PropertyChangedEventArgs. To
create one such instance one must provide the property name that has changed. This makes it
relatively easy to abstract. The default implementation should expose a protected method that
takes as argument the name of the property. The method itself constructs the
PropertyChangedEventArgs instance and uses it to properly raise the event.
Since the method is protected, the only way to access it from a different class is through
inheritance, this solve the problem regarding the sender of the event as the initiator is the instance
itself. Using the this keyword and the property name parameter the method has all the information
required to raise the event accordingly.
Providing the name of the property as a hardcoded string may yield problems when renaming
them. The rename function within Visual Studio does not change hardcoded strings that contain
the same value. If a property is renamed, then all places where it would be used to raise the
PropertyChanged event also need to be updated.
To solve this problem one can use the nameof operator available with C# 6.0, in case of using an
older version for various reasons, one can use the CallerMemberNameAttribute and have the
compiler fill in the property name automatically.
Having a base implementation that makes it easy to notify upon property changes makes it ideal
for a candidate for a base class to domain objects. Since they should be observable such that
controls can be bound directly to them they should all derive from the default
INotifyPropertyChanged implementation.
Calling the protected method with the property name to notify that it has changed leads to a lot
of copy and paste code which tends to become less challenging. If this becomes an issue or a lot
of unit tests need to be written in order to test whether the event is raised with the appropriate
property name, there are a few alternatives to remedy this.
If unit tests become a problem, then one can write a generic unit test class and rely on reflection
to test each and every public property that when it is updated the PropertyChanged event is raised
with the appropriate property name.
Interactive Applications in .NET - Implementing the Machine
26
If calling a method in each property becomes problematic then one can rely on Aspect Oriented
Programming and use PostSharp, or any other tool, to have INotifyPropertyChanged automatically
implemented by all types matching a pattern, such as all classes that are in a specific namespace.
This technique will speed development time a little, but all the observable behavior that is required
will be provided out of the box by any domain object without any additional code.
Besides domain objects, there is the interactive view model. Any derivative of the
InteractiveViewModel class should be able to define a number of action states in which the view
model processes something.
Each action state actually maps to a method that can be either synchronous, for quick operations,
or asynchronous. The view model can be in exactly one state at a time which is either a quiet state
or an action state. The name of the state is resembled through a string which allows it to be just
about any value except null.
Within the view model constructor, the user needs to make sure to transition to an initial state. If
the state of the view model is queried before it actually transitions to one the State property
accessor will throw an InvalidOperationException as the view model was not properly initialized.
At any given point, action states can be created using a string as the name of the state, state
names are case insensitive, and an associated method that performs the actual action. For
reliability, it is best that all action states are created in the constructor, this will ensure that all
action states are defined when the instance is made available.
When an interactive view model transitions to a state which was previously marked as an action
state, the mapped method is executed. Before actually invoking the method the state of the
interactive view model is updated in the same sequence and not at a later point in time. This
means that when calling TransitionToAsync, the view model will update its state accordingly before
returning control to the caller.
Figure 5 contains a sequence diagram illustrating the interaction happening when transition from
one state to another. [13]
The method starts by checking whether the state that the interactive view model should transition
to is an action state. If that is the case, then the state is updated and all subscribers to the
PropertyChanged event are notified of the change. The first callbacks that get executed are those
that subscribed to the event and only after that the callback mapped to the action state is
executed! This is very important as the user interface can be informed of the transition before
actual execution is performed thus it can be updated accordingly.
Each method mapped to an action state must have one parameter of type ActionContext which
represents the context in which the action is being executed. One can query the action context to
determine the source state from which the interactive view model transitions and use it to
determine the next state. Before the mapped method or callback completes, it must provide the
name of the next state the interactive view model should transition.
Interactive Applications in .NET - Implementing the Machine
27
Instead of mapping the destination state of an action state when it is created it is provided by the
callback to the view model after it has executed. This offers great flexibility as based on what
happens within the action state the interactive view model can transition to one state in some
cases and to a different state in other cases.
At the end the state of the view model is updated with the latest state name returned through the
ActionContext instance, in case there were any action states, or the state which was initially
provided as parameter to the TransitionToAsync method.
One important note is that an action state is not constrained to the kind of destination state it
must provide. An action state may have as destination another action state which will result in a
chaining of actions. All these transitions are visible to the interface and depending on the currently
executing action the visual state may alter how controls are displayed.
FIGURE 5 TRANSITIONTOASYNC INTERACTION
:InteractiveViewModel
TransitionToAsync(state)
viewModelState:
ViewModelState
while
[TryGetActionState(state, out viewModelState)]
Property Changed
Subscriber
actionContext:
ActionContext
<<create>>
<<set>>State := state
NotifyPropertyChanged("State")
<<notify>>
<<await>>Execute(actionContext)
<<awaitable Task>>
<<set>>NextState := nextState
<<continuation>>
state := <<get>>NextState
<<set>>State := state
NotifyPropertyChanged("State")
<<notify>>
<<task completion
notification>>
One of the constraints that is not illustrated in the diagram in Figure 5 is that while an interactive
view model is in an action state, any attempt to call the TransitionToAsync method will end in an
Interactive Applications in .NET - Implementing the Machine
28
exception. In order for the interactive view model to transition to an action state it must either be
in a quiet state or the action state itself to be in initial state of the view model.
Since an interactive view model cannot be triggered to transition from one state to another while
in an action state it would be useful to be able to queue transition requests.
Behind the scenes, the view model stores the task which resembles the asynchronous execution
of the last transition. To be able to queue transition requests one would need to await the previous
transition task and only then make the request for the next transition.
Note that the task returned by TransitionToAsync only completes when the interactive view model
reaches a quiet state! This behavior needs to be maintained even for queued transition request.
When calling EnqueueTransitionToAsync the method should return a task that will complete only
when the transition towards the enqueued has completed. Figure 6 illustrates this.
FIGURE 6 ENQUEUING TRANSITIONS
interactiveViewModel:
InteractiveViewModel
EnqueueTransitionToAsync(state)
<<await current transition>>
<<await>>TransitionToAsync(state)
<<task completion
notification>>
Most, if not all, applications have to do with user input. Thus far the interactive view model is only
concerned about implementing the asynchronous model through a state machine. This is ideal
for a base class for interactive view models as the entire logic of transitioning and queueing
transition requests is all in one class and that class has no other responsibility. [11]
This increases code reuse and reliability as the InteractiveViewModel class has only one
responsibility which can be thoroughly analyzed and tested.
The next step is extending the class to work within a data context. Previously it was mentioned
that domain objects themselves should be observable and that they should be the data context
in which a view model operates.
While this may seem easy at first, there is a catch. When working with user input one must always
validate that input. The rule still applies to interactive view models. The class containing the core
Interactive Applications in .NET - Implementing the Machine
29
functionality cannot be simply derived and have an extra property holding the data context. The
derivative must provide a way that alongside data, validation errors are also provided.
XAML allows to specify the data context of a control through the DataContext property. Any
binding expression made on the respective control will look at the object set through the
DataContext property if a source is not specified. The intellisense is smart enough to know this
meaning that once a DataContext is set one can use auto complete to browse through the list of
available properties to bind to.
Since there is only one DataContext property, in order to provide both data and validation errors
to a control in order to bind to them, they must be packed into one object and the respective
instance to be used as the DataContext of data bound controls.
The type of the object housing both data and context is called ViewModelContext. It is not prefixed
with “Interactive” since it may be used in other view models that are not interactive. It contains a
reference to an object (it can be an object but as discussed previously, it would make sense to be
a domain object) and a reference to a read only observable collection containing items of type
ValidationError. ValidationResult from ComponentModel is not portable.
The ViewModelContext class is generic as the object containing data can be of various types, even
though binding would work even if the type of the property used in binding is of type object, it
would be best to not limit intellisense where there is no reason to do so.
The InteractiveViewModel which operates with a data context receives on the constructor a data
object, which is generic, and provides to the ViewModelContext the same object and a read only
observable collection proxy to a usual observable collection. This is to restrict the ability to edit
the list of errors from outside the view model. [14]
The observable collection of errors and the data object are exposed as protected properties which
makes them only available to derivatives. This way, any interactive view model is able to manage
the list of errors in their own way.
Figure 7 illustrates the static structure of the components using class diagrams. [13]
Interactive Applications in .NET - Implementing the Machine
30
FIGURE 7 STATIC STRUCTURE
InteractiveViewModel
#CreateActionState(name : string, action : Action<ActionStateContext>)
#TransitionToAsync(name : string) : Task
#TransitionToAsync(name : string, parameter : object) : Task
#EnqueueTransitionToAsync(name : string) : Task
#EnqueueTransitionToAsync(name : string, parameter : object) : Task
#BindCommand(command : ICommand, states : string[*]) : ICommand
#GetTransitionCommand(state : string) : ICommand
#GetEnqueuingTransitionCommand(state : string) : ICommand
#GetTransitionCommand(state : string, errorHandler : Action<ErrorContext>) : ICommand
#GetEnqueuingTransitionCommand(state : string, errorHandler : Action<ErrorContext>) : ICommand
#CreateActionState(name : string, asyncCancellableAction : Func<ActionStateContext, CancellationToken, Task>)
#CreateActionState(name : string, asyncAction : Func<ActionStateContext, Task>)
TDataModel
InteractiveViewModel
+<<create>>(dataModel : TDataModel)
#<<get>>DataModel : TDataModel TDataModel
ViewModelContext
+<<get>>DataModel : TDataModel
ValidationError
+<<get>>Message : string
+<<get>>MemberName : string
#Errors : ObservableCollection<ValidationError>*
+Errors : ReadOnlyObservableCollection<ValidationError>
*
+Context1
ErrorContext
+<<get>>CanTransition : bool
+<<get, set>>NextState : string
+<<get>>FaultState : string
+<<get>>IsCancelled : bool
/+<<get>>Exception : Exception
+<<get>>AggregateException : AggregateException
InteractiveViewModel1
ActionStateContext
+<<get>>Parameter : object
+<<get>>NextState : string
InteractiveViewModel1
+<<get>>PreviousState : string
As it can be noted, there is an ErrorContext class. Commands have no returning type (void) thus
they cannot be awaited but can be asynchronous methods. In order to be able to handle errors
that may happen during the execution of a trigger command, an error handler callback can be
Interactive Applications in .NET - Implementing the Machine
31
provided to the GetTransitionCommand method. This method creates a command that when
executed it will trigger a transition towards the state given as parameter to the method. If the
method execution fails in an exception, cancellation is also reported as exception, then the
provided handler is used to remedy the situation and stop the application from crashing.
Within the error handler one can check whether the exception that occurred was actually a
completed cancellation or if something bad actually happened. Based on its logic, the error
handler instructs the interactive view model to what state it should transition.
The BindCommand method simply wraps the provided command into a proxy which allows the
command to be made available only when the interactive view model is in one of the bound states.
Ultimately it is up to the wrapped command to tell whether it is truly available in a bound state or
not through its CanExecute method. [14]
4.1.Reactive Extensions
Reactive Extensions is a library which also helps in developing interactive applications, however
they do not rely on INotifyPropertyChanged interface, but more on IObservable and IObserver
interfaces. Sadly, controls on the user interface do not respond to notifications from objects
implementing these interfaces, however Reactive Extensions make use of observable collections.
One can use this library to create asynchronous data flows using collections and queries. This is
particularly useful at the view model level as data which is provided by the user can be used to
filter collections asynchronously. The application will show results as they become available and
not all at once.
The approach presented in this paper does not cover data queries and how they should load on
the user interface, however with Reactive Extensions one can bind the two and achieve a rich user
experience with ease. The two can complement each other and neither is a replacement for the
other.
Interactive Applications in .NET - Conclusions
32
5. Conclusions
This paper has presented an architectural approach towards developing applications in general,
but more centered around being able to create rich user interfaces with tools that are already
available.
The originality of this work is illustrated through the implementation of a library that blends in
with the .NET Framework and can be easily integrated, even partially, in any application. The library
uses abstractions provided by the underlying framework without introducing any new ones that
require workarounds in certain scenarios.
The library itself is an extension of the framework not only using its abstractions but also
promoting language features available in both C# and Visual Basic .NET, the library bridges
concepts and tools in an effort to ease the creation of applications that provide a rich user
experience by using asynchronous programming and eliminating data races that tend to happen
in applications that use worker threads instead.
Interactive Applications in .NET - References
33
6. References
[1] R. C. Martin, The Clean Coder: A Code of Conduct for Professional Programmers, 1st ed.,
Prentice Hall, 2011.
[2] J. Albahari and B. Albahari, C# 5.0 in a Nutshell: The Definitive Reference, 5th ed., O'Reilly,
2012.
[3] A. Davies, Async in C# 5.0, 1st ed., O'Reilly Media, 2012.
[4] J. Smith, "Patterns - WPF Apps With The Model-View-ViewModel Design Pattern," MSDN
Magazine, vol. 24, no. 2, pp. 72-83, February 2009.
[5] E. Gamma, R. Helm, R. Johnson and J. Vlissides, Design Patterns: Elements of Reusable
Object-Oriented Software, Pearson Education, 1994.
[6] Microsoft Patterns & Practices Team, Microsoft® Application Architecture Guide (Patterns
& Practices), 2nd ed., Microsoft Press, 2009.
[7] R. C. Martin, Clean Code: A Handbook of Agile Software Craftsmanship, 1st ed., Prentice Hall,
2008.
[8] E. Evans, Domain-Driven Design: Tackling Complexity in the Heart of Software, Addison
Wesley, 2003.
[9] V. Vernon, Implementing Domain-Driven Design, 1st ed., Addison-Wesley Professional,
2013.
[10] E. Burris, Programming in the Large with Design Patterns, 1st ed., Pretty Print Press, 2012.
[11] V.-S. Tarquin, "MVVM - WPF Commanding with the State Machine Pattern," MSDN Magazine,
vol. 29, no. 11, pp. 58-61, November 2014.
[12] G. H. Mealy, "A Method for Synthesizing Sequential Circuits," Bell System Technical Journal,
p. 34: 5, September 1955.
[13] R. Miles and K. Hamilton, Learning UML 2.0, O'Reilly, 2006.
[14] E. Freeman, B. Bates, K. Sierra and E. Robson, Head First Design Patterns, 1st ed., O'Reilly
Media, 2004.

Weitere ähnliche Inhalte

Was ist angesagt?

Report file on Web technology(html5 and css3)
Report file on Web technology(html5 and css3)Report file on Web technology(html5 and css3)
Report file on Web technology(html5 and css3)PCG Solution
 
Major File On web Development
Major File On web Development Major File On web Development
Major File On web Development Love Kothari
 
Pick Your Poison – Mobile Web, Native, or Hybrid? - Denver Startup Week - Oct...
Pick Your Poison – Mobile Web, Native, or Hybrid? - Denver Startup Week - Oct...Pick Your Poison – Mobile Web, Native, or Hybrid? - Denver Startup Week - Oct...
Pick Your Poison – Mobile Web, Native, or Hybrid? - Denver Startup Week - Oct...Shane Church
 
Campus news feed
Campus news feedCampus news feed
Campus news feedNoopur Koli
 
Ethical consideration in open source software
Ethical consideration in open source softwareEthical consideration in open source software
Ethical consideration in open source softwareaamatya
 
Mse sept13 (3/3)
Mse sept13 (3/3)Mse sept13 (3/3)
Mse sept13 (3/3)IIITA
 
Ethical Consideration of Open Source Software
Ethical Consideration of Open Source SoftwareEthical Consideration of Open Source Software
Ethical Consideration of Open Source SoftwareLarry Jennings
 
mLearn Project 2012 Full Report
mLearn Project 2012 Full ReportmLearn Project 2012 Full Report
mLearn Project 2012 Full ReportmLearn
 

Was ist angesagt? (10)

Report file on Web technology(html5 and css3)
Report file on Web technology(html5 and css3)Report file on Web technology(html5 and css3)
Report file on Web technology(html5 and css3)
 
Infinitytech New
Infinitytech NewInfinitytech New
Infinitytech New
 
Major File On web Development
Major File On web Development Major File On web Development
Major File On web Development
 
Pick Your Poison – Mobile Web, Native, or Hybrid? - Denver Startup Week - Oct...
Pick Your Poison – Mobile Web, Native, or Hybrid? - Denver Startup Week - Oct...Pick Your Poison – Mobile Web, Native, or Hybrid? - Denver Startup Week - Oct...
Pick Your Poison – Mobile Web, Native, or Hybrid? - Denver Startup Week - Oct...
 
Campus news feed
Campus news feedCampus news feed
Campus news feed
 
Ethical consideration in open source software
Ethical consideration in open source softwareEthical consideration in open source software
Ethical consideration in open source software
 
Mse sept13 (3/3)
Mse sept13 (3/3)Mse sept13 (3/3)
Mse sept13 (3/3)
 
Ethical Consideration of Open Source Software
Ethical Consideration of Open Source SoftwareEthical Consideration of Open Source Software
Ethical Consideration of Open Source Software
 
mLearn Project 2012 Full Report
mLearn Project 2012 Full ReportmLearn Project 2012 Full Report
mLearn Project 2012 Full Report
 
Youth Led Tech Curriculum Day 22
Youth Led Tech Curriculum Day 22Youth Led Tech Curriculum Day 22
Youth Led Tech Curriculum Day 22
 

Andere mochten auch

Verkenners Seizoen 2008/2009
Verkenners Seizoen 2008/2009Verkenners Seizoen 2008/2009
Verkenners Seizoen 2008/2009Tom Heintzberger
 
Green Collar Jobs And Your Community
Green Collar Jobs And Your CommunityGreen Collar Jobs And Your Community
Green Collar Jobs And Your Communityewesserle
 
Actividad 5 compartir presentación en línea angel orlando chi meza
Actividad 5 compartir presentación en línea angel orlando chi mezaActividad 5 compartir presentación en línea angel orlando chi meza
Actividad 5 compartir presentación en línea angel orlando chi mezaPersonal Assistant, LLC.
 
Control de la potència en aparcaments municipals
Control de la potència en aparcaments municipalsControl de la potència en aparcaments municipals
Control de la potència en aparcaments municipalsAMTU
 
Ag100 twickenham residence_004
Ag100 twickenham residence_004Ag100 twickenham residence_004
Ag100 twickenham residence_004Guy Morgan-Harris
 
Smart cities presente y futuro
Smart cities presente y futuroSmart cities presente y futuro
Smart cities presente y futuroAitor Ibañez
 
COOP_Igor Nesterenko_Reference
COOP_Igor Nesterenko_ReferenceCOOP_Igor Nesterenko_Reference
COOP_Igor Nesterenko_ReferenceIgor Nesterenko
 
Jefflin Brochure
Jefflin BrochureJefflin Brochure
Jefflin Brochurejeffklin
 
Solo in italia
Solo in italiaSolo in italia
Solo in italia6unmacello
 
SNACKS - DEEMAH PRODUCT CATALOG
SNACKS - DEEMAH PRODUCT CATALOGSNACKS - DEEMAH PRODUCT CATALOG
SNACKS - DEEMAH PRODUCT CATALOGStanley Cayari
 
Virtualización de Archivos - F5 Networks
Virtualización de Archivos - F5 NetworksVirtualización de Archivos - F5 Networks
Virtualización de Archivos - F5 NetworksAEC Networks
 
Office 1 summary report
Office 1 summary reportOffice 1 summary report
Office 1 summary reportguest87cb3bd
 

Andere mochten auch (20)

Verkenners Seizoen 2008/2009
Verkenners Seizoen 2008/2009Verkenners Seizoen 2008/2009
Verkenners Seizoen 2008/2009
 
Авазханов Алим + Автопарк
Авазханов Алим + АвтопаркАвазханов Алим + Автопарк
Авазханов Алим + Автопарк
 
Testdoc
TestdocTestdoc
Testdoc
 
Green Collar Jobs And Your Community
Green Collar Jobs And Your CommunityGreen Collar Jobs And Your Community
Green Collar Jobs And Your Community
 
Actividad 5 compartir presentación en línea angel orlando chi meza
Actividad 5 compartir presentación en línea angel orlando chi mezaActividad 5 compartir presentación en línea angel orlando chi meza
Actividad 5 compartir presentación en línea angel orlando chi meza
 
Barker :: Cartas Mahatmas
Barker :: Cartas MahatmasBarker :: Cartas Mahatmas
Barker :: Cartas Mahatmas
 
Control de la potència en aparcaments municipals
Control de la potència en aparcaments municipalsControl de la potència en aparcaments municipals
Control de la potència en aparcaments municipals
 
Rout project11
Rout project11Rout project11
Rout project11
 
Ag100 twickenham residence_004
Ag100 twickenham residence_004Ag100 twickenham residence_004
Ag100 twickenham residence_004
 
Present 1
Present 1Present 1
Present 1
 
Prezent Etwin
Prezent EtwinPrezent Etwin
Prezent Etwin
 
Smart cities presente y futuro
Smart cities presente y futuroSmart cities presente y futuro
Smart cities presente y futuro
 
COOP_Igor Nesterenko_Reference
COOP_Igor Nesterenko_ReferenceCOOP_Igor Nesterenko_Reference
COOP_Igor Nesterenko_Reference
 
Rout project4
Rout project4Rout project4
Rout project4
 
Jefflin Brochure
Jefflin BrochureJefflin Brochure
Jefflin Brochure
 
Solo in italia
Solo in italiaSolo in italia
Solo in italia
 
SNACKS - DEEMAH PRODUCT CATALOG
SNACKS - DEEMAH PRODUCT CATALOGSNACKS - DEEMAH PRODUCT CATALOG
SNACKS - DEEMAH PRODUCT CATALOG
 
Rout Project1
Rout Project1Rout Project1
Rout Project1
 
Virtualización de Archivos - F5 Networks
Virtualización de Archivos - F5 NetworksVirtualización de Archivos - F5 Networks
Virtualización de Archivos - F5 Networks
 
Office 1 summary report
Office 1 summary reportOffice 1 summary report
Office 1 summary report
 

Ähnlich wie Interactive Applications in .NET

Android project report learning np complete
Android project report learning np completeAndroid project report learning np complete
Android project report learning np completeSubha Deb
 
Decide if PhoneGap is for you as your mobile platform selection
Decide if PhoneGap is for you as your mobile platform selectionDecide if PhoneGap is for you as your mobile platform selection
Decide if PhoneGap is for you as your mobile platform selectionSalim M Bhonhariya
 
1 PROGRAM ISEM RESEARCH PAPER FOR APPLIED.docx
1 PROGRAM ISEM RESEARCH PAPER FOR APPLIED.docx1 PROGRAM ISEM RESEARCH PAPER FOR APPLIED.docx
1 PROGRAM ISEM RESEARCH PAPER FOR APPLIED.docxhoney725342
 
Running Head HUMAN-COMPUTER INTERFACE 1HUMAN-COMPUTER IN.docx
Running Head HUMAN-COMPUTER INTERFACE 1HUMAN-COMPUTER IN.docxRunning Head HUMAN-COMPUTER INTERFACE 1HUMAN-COMPUTER IN.docx
Running Head HUMAN-COMPUTER INTERFACE 1HUMAN-COMPUTER IN.docxpotmanandrea
 
Running Head HUMAN-COMPUTER INTERFACE 1HUMAN-COMPUTER IN.docx
Running Head HUMAN-COMPUTER INTERFACE 1HUMAN-COMPUTER IN.docxRunning Head HUMAN-COMPUTER INTERFACE 1HUMAN-COMPUTER IN.docx
Running Head HUMAN-COMPUTER INTERFACE 1HUMAN-COMPUTER IN.docxwlynn1
 
Running Head HUMAN-COMPUTER INTERFACE 1HUMAN-COMPUTER IN.docx
Running Head HUMAN-COMPUTER INTERFACE 1HUMAN-COMPUTER IN.docxRunning Head HUMAN-COMPUTER INTERFACE 1HUMAN-COMPUTER IN.docx
Running Head HUMAN-COMPUTER INTERFACE 1HUMAN-COMPUTER IN.docxjeanettehully
 
Whitepaper: Mobile Media Apps 101
Whitepaper: Mobile Media Apps 101Whitepaper: Mobile Media Apps 101
Whitepaper: Mobile Media Apps 101Polar Mobile
 
Mobile Application Project report
Mobile Application Project reportMobile Application Project report
Mobile Application Project reportChin2uuu
 
Steps For Building A Successful App For Your Business.pptx
Steps For Building A Successful App For Your Business.pptxSteps For Building A Successful App For Your Business.pptx
Steps For Building A Successful App For Your Business.pptxConcetto Labs
 
Mobile application Project report B.Tech Final year
Mobile application Project report B.Tech Final yearMobile application Project report B.Tech Final year
Mobile application Project report B.Tech Final yearChin2uuu
 
Why node.js for real time application development is a sage decision
Why node.js for real time application development is a sage decision Why node.js for real time application development is a sage decision
Why node.js for real time application development is a sage decision Katy Slemon
 
mobile app development tool-converted.pdf
mobile app development tool-converted.pdfmobile app development tool-converted.pdf
mobile app development tool-converted.pdfKatieLeslove1
 
TotalEconomicBenefitOfSparqlycode 1.2
TotalEconomicBenefitOfSparqlycode 1.2TotalEconomicBenefitOfSparqlycode 1.2
TotalEconomicBenefitOfSparqlycode 1.2Paul Worrall
 
How To Make Your App Available Offline.pdf
How To Make Your App Available Offline.pdfHow To Make Your App Available Offline.pdf
How To Make Your App Available Offline.pdfSatawaretechnologies1
 
Community App for Promoting Cross-Cultural Interaction
Community App for Promoting Cross-Cultural InteractionCommunity App for Promoting Cross-Cultural Interaction
Community App for Promoting Cross-Cultural InteractionMike Taylor
 
Community App for Promoting Cross-Cultural Interaction
Community App for Promoting Cross-Cultural InteractionCommunity App for Promoting Cross-Cultural Interaction
Community App for Promoting Cross-Cultural InteractionMike Taylor
 

Ähnlich wie Interactive Applications in .NET (20)

Android project report learning np complete
Android project report learning np completeAndroid project report learning np complete
Android project report learning np complete
 
Decide if PhoneGap is for you as your mobile platform selection
Decide if PhoneGap is for you as your mobile platform selectionDecide if PhoneGap is for you as your mobile platform selection
Decide if PhoneGap is for you as your mobile platform selection
 
1 PROGRAM ISEM RESEARCH PAPER FOR APPLIED.docx
1 PROGRAM ISEM RESEARCH PAPER FOR APPLIED.docx1 PROGRAM ISEM RESEARCH PAPER FOR APPLIED.docx
1 PROGRAM ISEM RESEARCH PAPER FOR APPLIED.docx
 
Running Head HUMAN-COMPUTER INTERFACE 1HUMAN-COMPUTER IN.docx
Running Head HUMAN-COMPUTER INTERFACE 1HUMAN-COMPUTER IN.docxRunning Head HUMAN-COMPUTER INTERFACE 1HUMAN-COMPUTER IN.docx
Running Head HUMAN-COMPUTER INTERFACE 1HUMAN-COMPUTER IN.docx
 
Running Head HUMAN-COMPUTER INTERFACE 1HUMAN-COMPUTER IN.docx
Running Head HUMAN-COMPUTER INTERFACE 1HUMAN-COMPUTER IN.docxRunning Head HUMAN-COMPUTER INTERFACE 1HUMAN-COMPUTER IN.docx
Running Head HUMAN-COMPUTER INTERFACE 1HUMAN-COMPUTER IN.docx
 
Running Head HUMAN-COMPUTER INTERFACE 1HUMAN-COMPUTER IN.docx
Running Head HUMAN-COMPUTER INTERFACE 1HUMAN-COMPUTER IN.docxRunning Head HUMAN-COMPUTER INTERFACE 1HUMAN-COMPUTER IN.docx
Running Head HUMAN-COMPUTER INTERFACE 1HUMAN-COMPUTER IN.docx
 
Whitepaper: Mobile Media Apps 101
Whitepaper: Mobile Media Apps 101Whitepaper: Mobile Media Apps 101
Whitepaper: Mobile Media Apps 101
 
Mobile Application Project report
Mobile Application Project reportMobile Application Project report
Mobile Application Project report
 
Steps For Building A Successful App For Your Business.pptx
Steps For Building A Successful App For Your Business.pptxSteps For Building A Successful App For Your Business.pptx
Steps For Building A Successful App For Your Business.pptx
 
Mobile application Project report B.Tech Final year
Mobile application Project report B.Tech Final yearMobile application Project report B.Tech Final year
Mobile application Project report B.Tech Final year
 
Why node.js for real time application development is a sage decision
Why node.js for real time application development is a sage decision Why node.js for real time application development is a sage decision
Why node.js for real time application development is a sage decision
 
mobile app development tool-converted.pdf
mobile app development tool-converted.pdfmobile app development tool-converted.pdf
mobile app development tool-converted.pdf
 
Fundamentals of Mobile App Development Technology
Fundamentals of Mobile App Development TechnologyFundamentals of Mobile App Development Technology
Fundamentals of Mobile App Development Technology
 
Android app developer in india
Android app developer in indiaAndroid app developer in india
Android app developer in india
 
how to choose right mobile app development tools
how to choose right mobile app development toolshow to choose right mobile app development tools
how to choose right mobile app development tools
 
TotalEconomicBenefitOfSparqlycode 1.2
TotalEconomicBenefitOfSparqlycode 1.2TotalEconomicBenefitOfSparqlycode 1.2
TotalEconomicBenefitOfSparqlycode 1.2
 
How To Make Your App Available Offline.pdf
How To Make Your App Available Offline.pdfHow To Make Your App Available Offline.pdf
How To Make Your App Available Offline.pdf
 
Community App for Promoting Cross-Cultural Interaction
Community App for Promoting Cross-Cultural InteractionCommunity App for Promoting Cross-Cultural Interaction
Community App for Promoting Cross-Cultural Interaction
 
Community App for Promoting Cross-Cultural Interaction
Community App for Promoting Cross-Cultural InteractionCommunity App for Promoting Cross-Cultural Interaction
Community App for Promoting Cross-Cultural Interaction
 
[IJCT-V3I2P36] Authors: Amarbir Singh
[IJCT-V3I2P36] Authors: Amarbir Singh[IJCT-V3I2P36] Authors: Amarbir Singh
[IJCT-V3I2P36] Authors: Amarbir Singh
 

Kürzlich hochgeladen

MANUFACTURING PROCESS-II UNIT-1 THEORY OF METAL CUTTING
MANUFACTURING PROCESS-II UNIT-1 THEORY OF METAL CUTTINGMANUFACTURING PROCESS-II UNIT-1 THEORY OF METAL CUTTING
MANUFACTURING PROCESS-II UNIT-1 THEORY OF METAL CUTTINGSIVASHANKAR N
 
Extrusion Processes and Their Limitations
Extrusion Processes and Their LimitationsExtrusion Processes and Their Limitations
Extrusion Processes and Their Limitations120cr0395
 
MANUFACTURING PROCESS-II UNIT-2 LATHE MACHINE
MANUFACTURING PROCESS-II UNIT-2 LATHE MACHINEMANUFACTURING PROCESS-II UNIT-2 LATHE MACHINE
MANUFACTURING PROCESS-II UNIT-2 LATHE MACHINESIVASHANKAR N
 
Introduction to IEEE STANDARDS and its different types.pptx
Introduction to IEEE STANDARDS and its different types.pptxIntroduction to IEEE STANDARDS and its different types.pptx
Introduction to IEEE STANDARDS and its different types.pptxupamatechverse
 
UNIT-III FMM. DIMENSIONAL ANALYSIS
UNIT-III FMM.        DIMENSIONAL ANALYSISUNIT-III FMM.        DIMENSIONAL ANALYSIS
UNIT-III FMM. DIMENSIONAL ANALYSISrknatarajan
 
Introduction to Multiple Access Protocol.pptx
Introduction to Multiple Access Protocol.pptxIntroduction to Multiple Access Protocol.pptx
Introduction to Multiple Access Protocol.pptxupamatechverse
 
Call Girls Service Nashik Vaishnavi 7001305949 Independent Escort Service Nashik
Call Girls Service Nashik Vaishnavi 7001305949 Independent Escort Service NashikCall Girls Service Nashik Vaishnavi 7001305949 Independent Escort Service Nashik
Call Girls Service Nashik Vaishnavi 7001305949 Independent Escort Service NashikCall Girls in Nagpur High Profile
 
(ANVI) Koregaon Park Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...
(ANVI) Koregaon Park Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...(ANVI) Koregaon Park Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...
(ANVI) Koregaon Park Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...ranjana rawat
 
The Most Attractive Pune Call Girls Manchar 8250192130 Will You Miss This Cha...
The Most Attractive Pune Call Girls Manchar 8250192130 Will You Miss This Cha...The Most Attractive Pune Call Girls Manchar 8250192130 Will You Miss This Cha...
The Most Attractive Pune Call Girls Manchar 8250192130 Will You Miss This Cha...ranjana rawat
 
Call Girls Pimpri Chinchwad Call Me 7737669865 Budget Friendly No Advance Boo...
Call Girls Pimpri Chinchwad Call Me 7737669865 Budget Friendly No Advance Boo...Call Girls Pimpri Chinchwad Call Me 7737669865 Budget Friendly No Advance Boo...
Call Girls Pimpri Chinchwad Call Me 7737669865 Budget Friendly No Advance Boo...roncy bisnoi
 
UNIT-V FMM.HYDRAULIC TURBINE - Construction and working
UNIT-V FMM.HYDRAULIC TURBINE - Construction and workingUNIT-V FMM.HYDRAULIC TURBINE - Construction and working
UNIT-V FMM.HYDRAULIC TURBINE - Construction and workingrknatarajan
 
UNIT - IV - Air Compressors and its Performance
UNIT - IV - Air Compressors and its PerformanceUNIT - IV - Air Compressors and its Performance
UNIT - IV - Air Compressors and its Performancesivaprakash250
 
AKTU Computer Networks notes --- Unit 3.pdf
AKTU Computer Networks notes ---  Unit 3.pdfAKTU Computer Networks notes ---  Unit 3.pdf
AKTU Computer Networks notes --- Unit 3.pdfankushspencer015
 
High Profile Call Girls Nagpur Isha Call 7001035870 Meet With Nagpur Escorts
High Profile Call Girls Nagpur Isha Call 7001035870 Meet With Nagpur EscortsHigh Profile Call Girls Nagpur Isha Call 7001035870 Meet With Nagpur Escorts
High Profile Call Girls Nagpur Isha Call 7001035870 Meet With Nagpur Escortsranjana rawat
 
(PRIYA) Rajgurunagar Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...
(PRIYA) Rajgurunagar Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...(PRIYA) Rajgurunagar Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...
(PRIYA) Rajgurunagar Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...ranjana rawat
 
Russian Call Girls in Nagpur Grishma Call 7001035870 Meet With Nagpur Escorts
Russian Call Girls in Nagpur Grishma Call 7001035870 Meet With Nagpur EscortsRussian Call Girls in Nagpur Grishma Call 7001035870 Meet With Nagpur Escorts
Russian Call Girls in Nagpur Grishma Call 7001035870 Meet With Nagpur EscortsCall Girls in Nagpur High Profile
 
Glass Ceramics: Processing and Properties
Glass Ceramics: Processing and PropertiesGlass Ceramics: Processing and Properties
Glass Ceramics: Processing and PropertiesPrabhanshu Chaturvedi
 
Call for Papers - African Journal of Biological Sciences, E-ISSN: 2663-2187, ...
Call for Papers - African Journal of Biological Sciences, E-ISSN: 2663-2187, ...Call for Papers - African Journal of Biological Sciences, E-ISSN: 2663-2187, ...
Call for Papers - African Journal of Biological Sciences, E-ISSN: 2663-2187, ...Christo Ananth
 

Kürzlich hochgeladen (20)

MANUFACTURING PROCESS-II UNIT-1 THEORY OF METAL CUTTING
MANUFACTURING PROCESS-II UNIT-1 THEORY OF METAL CUTTINGMANUFACTURING PROCESS-II UNIT-1 THEORY OF METAL CUTTING
MANUFACTURING PROCESS-II UNIT-1 THEORY OF METAL CUTTING
 
Extrusion Processes and Their Limitations
Extrusion Processes and Their LimitationsExtrusion Processes and Their Limitations
Extrusion Processes and Their Limitations
 
MANUFACTURING PROCESS-II UNIT-2 LATHE MACHINE
MANUFACTURING PROCESS-II UNIT-2 LATHE MACHINEMANUFACTURING PROCESS-II UNIT-2 LATHE MACHINE
MANUFACTURING PROCESS-II UNIT-2 LATHE MACHINE
 
Introduction to IEEE STANDARDS and its different types.pptx
Introduction to IEEE STANDARDS and its different types.pptxIntroduction to IEEE STANDARDS and its different types.pptx
Introduction to IEEE STANDARDS and its different types.pptx
 
UNIT-III FMM. DIMENSIONAL ANALYSIS
UNIT-III FMM.        DIMENSIONAL ANALYSISUNIT-III FMM.        DIMENSIONAL ANALYSIS
UNIT-III FMM. DIMENSIONAL ANALYSIS
 
Introduction to Multiple Access Protocol.pptx
Introduction to Multiple Access Protocol.pptxIntroduction to Multiple Access Protocol.pptx
Introduction to Multiple Access Protocol.pptx
 
Call Girls Service Nashik Vaishnavi 7001305949 Independent Escort Service Nashik
Call Girls Service Nashik Vaishnavi 7001305949 Independent Escort Service NashikCall Girls Service Nashik Vaishnavi 7001305949 Independent Escort Service Nashik
Call Girls Service Nashik Vaishnavi 7001305949 Independent Escort Service Nashik
 
(ANVI) Koregaon Park Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...
(ANVI) Koregaon Park Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...(ANVI) Koregaon Park Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...
(ANVI) Koregaon Park Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...
 
The Most Attractive Pune Call Girls Manchar 8250192130 Will You Miss This Cha...
The Most Attractive Pune Call Girls Manchar 8250192130 Will You Miss This Cha...The Most Attractive Pune Call Girls Manchar 8250192130 Will You Miss This Cha...
The Most Attractive Pune Call Girls Manchar 8250192130 Will You Miss This Cha...
 
(INDIRA) Call Girl Aurangabad Call Now 8617697112 Aurangabad Escorts 24x7
(INDIRA) Call Girl Aurangabad Call Now 8617697112 Aurangabad Escorts 24x7(INDIRA) Call Girl Aurangabad Call Now 8617697112 Aurangabad Escorts 24x7
(INDIRA) Call Girl Aurangabad Call Now 8617697112 Aurangabad Escorts 24x7
 
Call Girls Pimpri Chinchwad Call Me 7737669865 Budget Friendly No Advance Boo...
Call Girls Pimpri Chinchwad Call Me 7737669865 Budget Friendly No Advance Boo...Call Girls Pimpri Chinchwad Call Me 7737669865 Budget Friendly No Advance Boo...
Call Girls Pimpri Chinchwad Call Me 7737669865 Budget Friendly No Advance Boo...
 
UNIT-V FMM.HYDRAULIC TURBINE - Construction and working
UNIT-V FMM.HYDRAULIC TURBINE - Construction and workingUNIT-V FMM.HYDRAULIC TURBINE - Construction and working
UNIT-V FMM.HYDRAULIC TURBINE - Construction and working
 
UNIT - IV - Air Compressors and its Performance
UNIT - IV - Air Compressors and its PerformanceUNIT - IV - Air Compressors and its Performance
UNIT - IV - Air Compressors and its Performance
 
AKTU Computer Networks notes --- Unit 3.pdf
AKTU Computer Networks notes ---  Unit 3.pdfAKTU Computer Networks notes ---  Unit 3.pdf
AKTU Computer Networks notes --- Unit 3.pdf
 
High Profile Call Girls Nagpur Isha Call 7001035870 Meet With Nagpur Escorts
High Profile Call Girls Nagpur Isha Call 7001035870 Meet With Nagpur EscortsHigh Profile Call Girls Nagpur Isha Call 7001035870 Meet With Nagpur Escorts
High Profile Call Girls Nagpur Isha Call 7001035870 Meet With Nagpur Escorts
 
Roadmap to Membership of RICS - Pathways and Routes
Roadmap to Membership of RICS - Pathways and RoutesRoadmap to Membership of RICS - Pathways and Routes
Roadmap to Membership of RICS - Pathways and Routes
 
(PRIYA) Rajgurunagar Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...
(PRIYA) Rajgurunagar Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...(PRIYA) Rajgurunagar Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...
(PRIYA) Rajgurunagar Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...
 
Russian Call Girls in Nagpur Grishma Call 7001035870 Meet With Nagpur Escorts
Russian Call Girls in Nagpur Grishma Call 7001035870 Meet With Nagpur EscortsRussian Call Girls in Nagpur Grishma Call 7001035870 Meet With Nagpur Escorts
Russian Call Girls in Nagpur Grishma Call 7001035870 Meet With Nagpur Escorts
 
Glass Ceramics: Processing and Properties
Glass Ceramics: Processing and PropertiesGlass Ceramics: Processing and Properties
Glass Ceramics: Processing and Properties
 
Call for Papers - African Journal of Biological Sciences, E-ISSN: 2663-2187, ...
Call for Papers - African Journal of Biological Sciences, E-ISSN: 2663-2187, ...Call for Papers - African Journal of Biological Sciences, E-ISSN: 2663-2187, ...
Call for Papers - African Journal of Biological Sciences, E-ISSN: 2663-2187, ...
 

Interactive Applications in .NET

  • 1. INTERACTIVE APPLICATIONS IN .NET Master of Software Engineering AUTHOR ANDREI FANGLI SCIENTIFIC COORDINATOR DR. IOAN LAZĂR JUNE 2016 "BABEȘ-BOLYAI" UNIVERSITY, FACULTY OF MATHEMATICS AND COMPUTER SCIENCE
  • 2. Interactive Applications in .NET - Table of Contents Table of Contents 1. Applications Today................................................................................................................................................3 2. Asynchronous Programming.............................................................................................................................5 3. Architectural Approach..................................................................................................................................... 11 3.1. Model-View-ViewModel......................................................................................................................... 14 3.2. Defining the Context: Observable Domain Objects ..................................................................... 15 3.3. Asynchronous Model ............................................................................................................................... 17 3.4. Validation...................................................................................................................................................... 20 3.5. Visual State Manager ............................................................................................................................... 23 4. Implementing the Machine............................................................................................................................. 25 4.1. Reactive Extensions................................................................................................................................... 31 5. Conclusions........................................................................................................................................................... 32 6. References ............................................................................................................................................................. 33
  • 3. Interactive Applications in .NET - Applications Today 3 1. Applications Today A few years back, the number of applications available to the general public was rather small compared to their number today. Most of them were huge, enterprise level, applications that serve the needs of a company, after all, who is paying for all that effort? Developing software was harder, resources were limited and sometimes difficult to come by even though the Internet was generally available. As years went by and developer tools got rich and richer, more people jumped on the boat of software development. Creating software is still hard, but not as hard as it was 10 years ago. Making a desktop application by one self is a tiring effort as it requires a lot of features to even compete with the software already available. Not to mention user interaction. When tablets and smartphones came out, it was a first sign that there will be a boom in the numbers of developers. Once Software Development Kits came available for creating applications for various mobile platforms the trigger was pulled, and the explosion happened. There are literally tons of mobile applications. Anyone with little knowledge about writing code can download one of these Software Developments Kits and are already writing their application. Having virtual stores, in contrast to classic desktop applications, for mobile applications is a bonus as it offers a degree of security, a user is not going to any site to download free software, it is the official store for a mobile platform. Nothing should get in there without proper verification. These stores do not require from the application that is being published to be complex, in fact any simple application can make its way to the store without much problem. There are some that simply keep the score for a game of cards, some that just store one list where a user can only add and remove items to it. Tablets and smartphones are not meant for heavy duty computations; they are accessories that fit in pockets or really small bags. They are meant to be useful in most if not all situations. Some people spent some of their time with their friends playing card games, how useful it is having the phone keep the score rather than memorizing it? How useful is it to have a “to-do” list on a phone than instead of a piece of paper for which one also needs a pen to be able to write on? Tablets and smartphones have a lot of small and simple applications. This is the perfect environment for a single person to write an application that ends up being used by a lot of people. Tools available today make it really easy to write such applications, there are hundreds of libraries available that help in solving specific problems, there are a lot of Q&A sites, blogs and books that can aid just about anyone to create their own application. [1] This boom in software developers is both beneficial and somewhat damaging. Besides the risk to security as scam applications that somehow get past store verification and get published there is also the risk of bad software. Not as in ill-intended applications that drain battery or do some other damaging action on purpose. It is easy to write bad code, too easy. One can write all their
  • 4. Interactive Applications in .NET - Applications Today 4 logic in the code-behind of a page without using a single await statement. Besides having a bulk of non-reusable code that cannot be even tested automatically, it does not have a rich user experience. The user needs to wait for the application to finish whatever it is processing, or rather wait until the web service the mobile application has invoked returns as the phone itself should not do any heavy duty operations. [1] Applications today must be responsive! The user is in charge of their phone, not the other way around. Any mobile application that is not responsive sits on the same shelf with broken applications. The developer must take into consideration that at any point in time there may be an incoming call or the user simply needs to do something else with their phone. At any point in time the application must be ready to respond to what the user wants. Practically, it is impossible to respond in the exact same instant, it may be damaging to do so as an interrupt right in the middle of a write operation could corrupt the file that is being saved. [2] On the other hand, everything is from the perspective of the user. A small delay since the user has tapped the cancel button until it actually happens is acceptable. It is difficult, if not impossible, for a human being to tell whether the device responded exactly when the button was tapped or a few hundred milliseconds later. In order to be able to handle multiple events, or at least apparently handle them, one needs to consider parallel programming or asynchronous programming. Parallel programming comes with its own trouble of synchronization and multiple worker threads, joining threads and so on. Asynchronous programming, on the other hand, may be the best fit for allowing developers to create rich user interfaces. Asynchronous programming does not necessarily mean to move all computation on a separate thread so the user interface thread is free to receive other events and interact with the user. If small chunks of code are executed in a sequence in such a way that a tap event or an income phone call may come between them and eventually changing how the remaining chunks of code in the sequence are executed, then it is possible to give the impression that the application is doing multiple things in parallel when in fact it is doing little bits of more things giving the impression of parallel execution. [2] As long as there is visual feedback and the users are free to interact with the application and with their phone they will not tell the difference. Probably they do not even care about what is beneath the interface as long as the application does the job. One way to make rich user interfaces and responsive applications without all the synchronization issues that parallel programming may bring is through the use of asynchronous programming.
  • 5. Interactive Applications in .NET - Asynchronous Programming 5 2. Asynchronous Programming In conventional programming, in order to stop a long running method from blocking the caller of that method one would create a new thread and have it execute the long running method. One issue with this approach is signaling when the operation has completed in order to make necessary user interface updates, but also make use of the result of the operation. [2] In asynchronous programming, parallelism does not happen outside of the operation, but rather inside. Parallelism is initiated inside the long running method only if it is necessary. [2] This promotes encapsulation since there is no need to know whether a method is long running or not in order to use a separate thread. If the user interface freezes because a method takes too much time to complete, the optimization happens within the method. Responsibility falls on the implementer to refine their code, not on the user. There is still the issue of signaling completion. Whenever an operation completes, regardless of whether it is synchronous or asynchronous, it is a must to have some way of knowing when it completed. Typically, asynchronous methods do not block the caller. They return control to them before doing any actual work. In order to either know when the operation completed or have a continuation to that operation, asynchronous methods either return an object that can be used in that way or take a callback that will be called when the operation completes. [2] The initial approach in .NET was to use callbacks for continuations. Operations that could be executed asynchronously, such as reading from a stream, have a BeginX/EndX pair of methods for the corresponding X method, which was synchronous. For instance, the asynchronous pair of methods for Read are BeginRead/EndRead. BeginRead would take a callback, among other parameters that are also available for the synchronous Read version, that was executed once the operation has completed. The method returned an object implementing IAsyncResult that has to be used as parameter when calling EndRead. [2] In some cases, it would be possible to have the callback executed right away since most, if not all, stream implementations use a buffer behind the scenes. If the buffer already had the necessary data that was requested for an asynchronous read, the callback would have been invoked right away with the result. On the other hand, if the buffer did not already have the necessary information, it would load into the buffer on a different thread and only afterwards it would invoke the callback. This is one of the advantages of asynchronous programming, sometimes the code is not executed on a different thread because it is not always necessary. Forcing parallel execution by moving the actual method invocation to a different thread cannot yield such advantages unless the entire method is decoupled.
  • 6. Interactive Applications in .NET - Asynchronous Programming 6 One of the issues with the callback approach is that it promotes unreadable code that is also hard to maintain or extend. For instance, asynchronously making a request to a web service will require a callback for continuation. If the call is successful, responds with HTTP status code 201 - Created, then another call needs to be made to a different web service. The second call happens insides the callback. If the second request fails, responds with HTTP status code 400 – Bad request, then the first request to the web service needs to be undone which will turn out to be another asynchronous call, with another callback. How would this be written in a synchronous fashion? Make the first request, if the response has status code 201 then proceed with second request, if that is unsuccessful then undo the first one. The code ends up really easy to read even if the actual requests are not extracted into separate methods. How would the code change when another web service needs to be called when the undo fails? For the asynchronous approach it would mean another callback, while for the synchronous approach is just another if with another line of code. Easy to test, easy to extend. In .NET callbacks are provided through parameters of delegate type. Parameters of this type, or event handlers, accept anonymous methods or lambda expression. As with functional programming, when using lambda expressions, one can create closures over certain objects thus when passing a callback to a BeginX method, one can use a lambda expression, instead of an ordinary method, and inside it to close some of the variables. This is extremely useful, but it also blocks any kind of method extraction from the callback unless code is made less readable. [2] There is no doubt that the callback approach has its benefits, most notably the fact that there is no need for an actual signaling mechanism as it is certain that the callback is executed only after the asynchronous operation has completed. However, this approach promotes code that is hard to read, hard to maintain. [2] The issue of handling exceptions does not need exemplification. The try… catch statement already makes code less friendly to eyes, but the real problem is resource management. With the callback approach one needs to manually dispose the resources they use since the using statement does not split into lambda expressions. Resources need to be created outside of the callback and disposed when they are no longer necessary, no matter what! This is a critical as an exception can be thrown either when calling the BeginX method, either in the callback if the asynchronous operation fails. Resource disposal needs to happen in either case! [2] Resources that require manual handling implement the IDisposable interface. Usually these types also define a finalizer to ensure that the resource is safely deallocated even when Dispose is not called. Relying on the finalizer to actually deallocate resources yields memory issues as the Common Language Runtime has a generational garbage collection system. Objects that will have their finalizers invoked will be promoted to at least generation 1, if the next garbage collection does not include generation 1 then these objects will get promoted to generation 2! To actually
  • 7. Interactive Applications in .NET - Asynchronous Programming 7 reclaim the memory occupied by generation 2 objects the entire memory used by the application needs to be cleaned. [2] Exception management is a big problem alongside readability with the callback approach. There are more issues with this approach, however it is clear that writing code having this in mind is not exactly that easy and there are too many things that could go wrong, now there are alternatives to this approach which solve most of the problems. Tasks symbolize a unit of work that may not have completed but can be used to either block until it has completed, enlist continuations for when the operation has completed thus blocking is avoided but the callback issue returns or await them in C# asynchronous methods. [2] Tasks were introduced in .NET 4; they represent an abstract concept that enables high level parallel programming. Threads are primitive structures on which other parallel concepts are built on, they do not easily enable fine-grained parallelism. It is difficult to compose little parallel operations using threads in contrast to Tasks. A Task is literally a delegate that gets executed on one thread or another depending on the task scheduler. [2] Tasks can be easily composed using operations such as WhenAll or WhenAny as the result of either of these methods is another Task. It is easy to write code that executes in parallel that at some point some operations need to wait on each other to complete before the overall operation can continue. [2] Since C# 5.0, the language has support for asynchronous programming. Developers are no longer required to make a big effort into writing asynchronous code. The async and await keywords have been introduced, any method decorated with async must either return a Task or void. The await keyword can be used on methods that return a Task. [2] One of the great advantages of async and wait is that it enables developers to write code that looks like synchronous code, but in fact it is asynchronous. All of the actual splitting and plumbing is done by the compiler behind the scenes. [2] Having language support is very important as it is a standard approach to this style of programming in the respective language, but also makes these concepts generally available directly in the language rather than some third party library. Plus, it is far less likely to have bugs in what the compiler translates than a third library would. Back to the web services example. Writing code synchronously it would look something like the snippet bellow: if (Request1().StatusCode == 201) if (Request2().Failed) UndoRequest1();
  • 8. Interactive Applications in .NET - Asynchronous Programming 8 Really simple, however to invoke web services requires a number of steps that could take enough to make a user interface freeze. First is the DNS1 lookup, then it’s the actual connection, serializing the request and sending it over Internet. Afterwards the service processes the request and responds. It is possible that the service invoked to take a bit to load, or the web host is too busy processing other requests and our request would eventually end up in a timeout. This is one example where code should be written in an asynchronously in an effort to keep the user interface responsive. Using the async and await is really simple and straight forward: if ((await Request1Async()).StatusCode == 201) if ((await Request2Async()).Failed) await UndoRequest1Async(); It does not seem to have changed much, however there are more implications than what it may seem. When the compiler encounters an await it splits the method in two. From a high point of view, everything before the await is extracted into one method and everything after it goes to another method. To make the link between the two, the compiler uses the awaiter that is returned by calling GetAwaiter on a Task to subscribe a continuation. When the awaited operation completes then the continuation will be executed which will contain the remainder of the asynchronous operation. [2] The method transformation that the compiler applies to an async decorated method do not change much from the initial approach with callbacks, the great advantage is that the compiler is generating the necessary callbacks rather than the developer. This reduces the likely hood of introducing bugs and also enable some of the code C# features, such as conditionals, loops, try.. catch and using statements. [2] Since the method is split into multiple, there is the problem of maintaining method state. Variables and parameters that were either defined or provided inside an asynchronous method must be available throughout the method regardless of whether the compiler decides to split the method. Besides just splitting the asynchronous method after await statements, the compiler actually transforms each async decorated method into a state machine. Parameters and variables are stored as the context of the state machine which is encapsulated inside an object of type Task which is returned by the async decorated method. When then asynchronous method completes then the returned task transitions to either RanToCompletion, Faulted or Canceled states. [2] Since the transformations done to an async method are somewhat similar to what a developer would write using the callback approach, one needs to ask. Where does the code actually execute? 1 DNS stands for Domain Name System. The overall principle of the system is to associate names to IP addresses so it would be easier for human beings to memorize the location of a web site.
  • 9. Interactive Applications in .NET - Asynchronous Programming 9 Is it a thread from the thread pool? Is it always a new thread created by the task scheduler? Where does code actually execute? This is an important issue because all graphical user interfaces that can be written with .NET (Windows Forms, Windows Presentation Foundation) or WindowsRT have a dedicated thread (UI Thread), for interacting with any user interface components. Changes to the user interface and events from their controls are all executed on the UI Thread, any attempt to change the user interface from a different thread ends with an exception. [2] The way most user interfaces work is that they implement a producer-consumer pattern where the consumer is the UI Thread and a producer can be anything. A click on a button, an event from the operating system and so on. As events happen, their handlers, which are nothing else than callbacks, are posted in an execution queue where they may be prioritized. The UI Thread is constantly inspecting this queue and when an item is available it removes it from the queue it and executes in on the UI Thread. [2] All tasks are scheduled by a task scheduler which behind the scenes uses a Synchronization Context to actually marshal the code. When a task is awaited, the awaiter actually captures the current Synchronization Context to subscribe the remained of the method. [2] If necessary, one can implement their own Synchronization Context and have full control over how tasks are actually executed. Each thread can have at most one Synchronization Context set, if there is none set then the default is used which actually relies on the thread pool to carry out the actual execution. [2] All graphical user interfaces that can be programmed through .NET or WindowsRT set a specialized Synchronization Context for the UI Thread. The respective instance can be obtained and passed down to view models, controllers or other types of objects as a means to marshal code unto the UI Thread. It is already known that this is how async and await does it. [2] Whenever an async method is awaited whose execution was initiated on the UI Thread, usually the click event handler of a button or within the Execute method for a command to which a button is bound to, the continuation is posted to the specialized Synchronization Context which relies on the UI Thread to carry our actual execution. Eventually, continuations end up on the UI Thread and the user interface can be safely updated. [2] Writing responsive user interfaces means to have visual feedback for whatever the user does or for whatever event happens under the hood. If a long running operation is started, it may entirely run on the UI thread, but that does not necessarily mean waiting for the long operation to finish until any event is handled. The beauty of asynchronous programming in C# is that async methods are actually fragmented into smaller pieces where each is scheduled one at a time. This fragmentation allows for other events to be pushed unto the UI Thread execution queue in between the smaller pieces and respond accordingly to those events and in time.
  • 10. Interactive Applications in .NET - Asynchronous Programming 10 One can carry out all their work on the UI Thread alone. If the code is written well it may seem to the user that the application actually runs multiple jobs in parallel. In truth it does not execute anything in parallel, it just does one little bit of multiple tasks at a time. Regardless of whether there is some real parallelism behind, the user interface stays responsive. The user can constantly interact with the application and based on its current state it may be able to carry out some operations and not others. While it all may seem fine with asynchronous methods in C#, there are a few subtle side effects that async methods have. [3] One of them are the fake awaits. It is possible for an async method to actually complete synchronously and return an already completed task. For instance, the snippet bellow relies on a cache to fetch data faster: [3] public async Task<string> GetMessageAsync() { if (IsMessageCached()) return messageFromCache; var message = await someService.GetANewMessageAsync(); Cache(message); return message; } If the message is cached, then it is fetched from there and the async method completes synchronously. On the other hand, if this is the first time the method is called, it is most likely that the message is not cached, thus the call to GetANewMessageAsync is made. Depending on what happens inside the awaited method the GetMessageAsync may return with a Task that is not yet completed. The same principle is applied recursively. [3] An async method will return prior to actually finishing when it will find a real await. These happen when a task that executes on a different thread is actually returned or when a call to Task.Yield() is awaited. The latter does nothing special. It simply forces the compiler to actually split the method in two having the side effect of having the async method actually return control to the caller when the call to Task.Yield() is made. This is a safe way of ensuring that the async method will always return control to the caller before it actually finishes. [2] One last topic to cover when it comes to asynchronous programming is cancellation. Like in most other platforms, cancellation is signaled. The operation that is being canceled has to check, from time to time, whether a cancellation has been signaled. [2] Cancellation is requested to a task through a CancellationToken. One can use CancellationTokenSource which exposes a token that can be passed to one or more tasks. To signal a cancellation request one must call the Cancel method on the CancellationTokenSource which in turn will mark the token with cancellation requested. [2]
  • 11. Interactive Applications in .NET - Architectural Approach 11 3. Architectural Approach While asynchronous programming can be beneficial to writing interactive applications, they are only part of the solution. In order to have a rich user interface it must also be updated constantly to show both available options depending on what the application is doing at that point, but also what information is available and whether new information is being retrieved from somewhere. Things such as progress bars, fade and other kind of animations make the user experience more pleasing, if a list of items just pops up without a smooth fade in animation the application will seem less user friendly. Starting with Windows Presentation Foundation and now also in WindowsRT, one can make use of the already available tools to write rich user interface applications. Controls already come with their own bag of animations which make the application pleasing, since they are out of the box it is likely to encounter the same animation as other applications and even what the operating system is using. This helps with the look and feel as just navigating through such an application will already make it familiar and inviting. [4] One critical part to writing good applications is how they are structured. For quite some time, user interfaces build with Visual Studio, either Windows Presentation Foundation for Windows Desktop, or WindowsRT for mobile platforms, use XAML to describe them. [4] XAML stands for eXtensible Application Markup Language, it is a derivative of XML2 and enables developers to create user interfaces, and not only, in a declarative meaner. Every XAML file is bound to a concrete class, the code within that class is referred to as code-behind. [4] Clearly, C# code will not go into the XAML file. On the other hand, in the code-behind class one can access anything that was defined in the corresponding XAML file. This is one of the reasons why the code-behind exists, to cover for anything that cannot be made through XAML, such as enabling or disabling buttons based on some event, handling button clicks and so on. This is where asynchronous programming comes into play. One can write an asynchronous event handler for handling what happens when, for instance, the user fills a form and clicks the save button. Right when the event handler starts, the button is available in the code behind and thus it can be disabled during the save operation. The save operation itself is asynchronous thus it is awaited, there is no telling how long it will take but during that time the button is disabled. When the save operation completes the button is enabled and the user is free to add another item. If the handler were to be synchronous, there would be no need to disable and enable the save button, but because of the compiler fragments the async methods, it is possible that the user to click the save button while the operation is being carried out and have the event handler executed once again before the first call is finished (see figure 1). 2 XML stands for eXtensible Markup Language. It was first introduced to help transfer data between applications.
  • 12. Interactive Applications in .NET - Architectural Approach 12 FIGURE 1: SYNCHRONOUS VS ASYNCHRONOUS EVENT HANDLERS Synchronous UI Thread 1st button click <<event handler>> SaveButton_Click 2nd button click <<event handler>> SaveButton_Click Asynchronous UI Thread 1st button click <<event handler>> SaveButton_Click 2nd button click <<event handler>> SaveButton_Click The synchronous way is simple and straight forward, however it may lead the user interface to freeze which leads to a very poor user experience. The asynchronous way illustrates both a problem and a feature. As it can be seen in figure 1, using asynchronous event handlers may lead to overlapping execution. It is possible to have multiple handlers in progress at the same, clearly it could lead to some problems if a user is allowed to save the same entity twice at the same time. Because of this, as previously mentioned, the developer must take extra steps in the code behind to ensure that the save button is unavailable while the associated action is being executed. On the other hand, other buttons may become available. For instance, while the application is saving an entity it could be possible to cancel that operation. Having a synchronous approach, clearly that cannot happen as easily as it can with an asynchronous approach. Imagine that instead of the second button click it would be a cancel button click event. That would signal the save operation to cancel which may either lead to actually cancelling the operation, or the cancellation to fail. It is possible that the user to click right the cancel button right when the entity was saved, thus canceling the operation means actually deleting the entity. Working with the code-behind is just one, less promoted way, to respond to events. XAML encourages binding controls to various properties in order to both provide data to them but also respond to events such as button clicks. [4]
  • 13. Interactive Applications in .NET - Architectural Approach 13 Data binding encourages separation of concerns, usually an object providing data and commands through properties is used as a binding source for a view. The binding source can raise specific events in order to inform the user interface to update itself. [4] The data source to which a control binds to may expose a number of properties, this is usually the case, which themselves become binding sources. Observer is a behavioral design pattern implies that an object, referred to as the subject, maintains a list of different objects, whose concrete type is unknown, referred to as observers. Whenever the subject changes it is responsible with notifying all observers about that change. [5] In .NET, the observer pattern is implemented using events which themselves are implemented using delegates. A delegate is a reference to a function. Through a delegate one can invoke a method that an object exposes, or not, as well as a static method. [2] It is possible to have an event handler, which is basically a method subscribed to an event, that is actually a private method. Events in .NET do not require the observer to implement any specific interface but rather have either a method with a specific signature or an adapter for it. Anonymous methods or lambda expressions can be used to subscribe to a method and actually have them call a private method of an object. The lambda expression is actually a closure around the instance whose method will be called. [2] User interface controls, not just Windows Presentation Foundation and WindowsRT ones, Windows Forms as well, rely on INotifyPropertyChanged interface in order to be notified whether the binding source has changed. It is not mandatory to implement this interface, an object that does not implement it can still be bound to, but the respective control will not receive update notifications and thus it will not update. [4] INotifyPropertyChanged exposes just one event, PropertyChanged which relies on the PropertyChangedEventHandler delegate. Most event handlers require a method with two parameters, an object which refers to the initiator of the event, the subject and an instance of EventArgs or one of its derivatives. In this case, when the event is raised a specialized EventArgs is sent which informs which property has changed through its PropertyName property. [4] Besides binding to data, views can also bind to commands. Command is a behavioral design pattern in which an object encapsulates the invocation to an operation. [5] In order to successfully bind to a command, a binding source needs to implement the ICommand interface. This interface exposes two operations, CanExecute(object) and Execute(object) alongside an event, CanExecuteChanged. [4] Basically, the object implementing this interface needs to be both a command and a subject. This is done in order to avoid pooling the CanExecute(object) method, when there is a chance that the result of the respective method to have changed, the CanExecuteChanged event is raised. This will
  • 14. Interactive Applications in .NET - Architectural Approach 14 make controls call CanExecute(object). Based on the result, the button becomes available or disabled. When a user clicks on a button, the Execute(object) method is called. The object parameter which is required by both methods is a value that can be optionally specified when binding to a command. This is useful for commands like navigating to a page. It page number itself does not have to be encapsulated inside the command object, but can be provided as a parameter. However useful, any change on the command parameter that is signaled to the user interface through the PropertyChanged event will not initiate a call to CanExecute(object)! 3.1.Model-View-ViewModel Separating views from business logic enhances code reusability but also testability. It is easy to test whether an object has the desired behavior when it can be passed input that would normally come from the user and see what it outputs. For application where the user interaction needs to be rich, there is need for an intermediary layer between the view and the business layer in order to properly handle the logic behind a view. [6] The Model-View-ViewModel is an architectural pattern focusing on separating the view and its logic from the business models of the application in an effort to separate concerns and thus obtain more granular, maintainable, testable and reusable code. [4] All data is provided to the view by the view model and all requests from the user are forwarded to the view model. The view model itself relies on a model, which can be a data model or any business object, to retrieve data and operate on (see Figure 2). FIGURE 2: MODEL-VIEW-VIEWMODEL OVERVIEW ViewModel <<binding>> <<property changed notifications>> Model View <<provides data>><<changes>> In this case, the view model is the binding source of the view. It provides both data and commands. This can lead to a lot of code duplication, for every model there should be a view model or something similar, as well as ending up with classes having multiple responsibilities. There are exceptions to the Single Responsibility Principal, but data and behavior should not be mixed together in the same class. [7]
  • 15. Interactive Applications in .NET - Architectural Approach 15 3.2.Defining the Context: Observable Domain Objects In Domain Driven Design, it is proposed to model the business layer around the domain for which the application is being implemented. While doing this, the model should be constantly presented and approved by domain experts in an effort to reduce the risk of misunderstanding and also help create a ubiquitous language. [8] There is more to Domain Driven Design than the above paragraph, but this paper focuses on describing an approach towards creating interactive applications in a clean and reliable way. This has an impact towards how certain concepts in Domain Driven Design are affected. The domain layer should contain only classes that are either entities, values or domain services. Entities are objects that have a thread of life in some way. For instance, in an application which manages movies, it is important that when a user is reading about a movie to be the same movie that the administrator introduced. Usually when changing one of the properties of an entity, it is not a new entity but the same one. [8] Value objects, on the other hand, are simple values. For instance, the length of a movie is a value as it is not important whether the value is created each time a movie is being loaded from the database or not. It can be stored as the number of minutes the movie lasts and when it is retrieved from the database a TimeSpan is created from that value. The difference between a value and an entity is that values should be immutable, when one wants to change a property of a value or the value itself, it is a new value rather than the same one with an update. [8] So far only data structures have been covered. There are more complex applications in which the software must perform an action that is domain specific. One of the most common examples is changing the currency of a sum. Accountants have a formula for how to transfer a sum from one currency to another besides the currency transfer rate and the source sum. It is likely that after a transfer the resulting sum needs to be rounded. The entire logic of transferring a sum from one currency to another is implemented in a domain service since these actually model operations on data rather than data itself. [8] Going strict by definitions, it would mean to have a number of types that model the domain in the business logic layer. A number of view models, a considerable part of them will map one-to- one with domain objects, that expose both data and behavior through commands for a view to bind to. Last but not least, a number of repositories for managing entities in a storage. The mapping between the business model and their respective view models can be done through an Anticorruption Layer [8]. But what would the view model wrapping the domain object do anyway? It would only expose the same properties as the model does only that the view model is observable. This is a direct violation of Don’t Repeat Yourself principle. Besides duplicating code, there is also the issue of circular references. The domain model is implemented however the business demands, if it demands circular references then there will be such associations. When working with references, which is mostly the case in .NET and other
  • 16. Interactive Applications in .NET - Architectural Approach 16 platforms, one must think of the relationships between objects as a graph, for what it truly is, and not as a tree, which is only a subset of all possible cases. How would the Anticorruption Layer fair with circular references? Extra checks would need to be set in place in order to avoid infinite loops or StackOverflowExceptions. That means a greater performance cost, more time spent until actual data is shown on the user interface. Writing view models for each domain model by hand rather than have a tool to generate them means more time spent by a developer on less engaging matters. Creating a tool to generate view models would seem like an appropriate challenge for a developer, but either approach needs to deal with the circular reference issue. Some sort of cache needs to be implemented in order to properly map the domain object graph to the view model object graph. [9] Last but not least, one could write a generic class that wraps an object and through reflection it automatically generates other view models for the wrapped object with a few exceptions such as strings, integers and other data types considered to be primitives. This approach eliminates intellisense completely as properties are implicit, not explicitly defined on the view model class. Any approach taken either increases development costs or end up in eliminating very useful features offered by the integrated development environment. The price needs to match the reward or this is a very bad deal. What if, the domain objects were themselves observable? What if, one could bind directly to them without any intermediary? If there is any circular reference between them, it is already set when it gets to the view. There is not duplicate code and there is no time wasted in doing so. In order to be able to bind to an object and automatically have the user interface updated when one of their properties change one must only implement INotifyPropertyChanged which exposes only one event. The entire subscriber list is managed by the delegate which is used to implement the event. All that is required is to raise the respective event when a property is being set. This is a very small price to pay when implementing domain entities and values for what is obtained in return. To ease development, one can offer a base implementation of INotifyPropertyChanged and simply derive all observable objects from there. The base implementation would provide a protected method for raising the respective event taking a string parameter which will resemble the property name that has changed.
  • 17. Interactive Applications in .NET - Architectural Approach 17 3.3.Asynchronous Model When domain objects become observable one can easily bind the user interface controls to them. Even view models themselves can subscribe to their events in order to carry out different operations. For instance, when the property of an entity changes it would be required to validate the updated entity. If there are any errors an observable collection of errors would be updated and thus any control that has bound to it will automatically display them. All user interface controls rely on objects that implement INotifyPropertyChanged and INotifyCollectionChanged interfaces to update themselves. They both only expose events for notifying when the subject has changed. Both the ObservableCollection<T> and ReadOnlyObservableCollection<T> are types present in .NET framework that implement these interfaces and they should be used to speed development. [4] One important aspect of software development besides data is behavior. Software is mostly about behavior; it is mostly about doing something over a dataset. Interactive application demand that the user has constant visual feedback, even when the application is busy carrying out a request, there is a progress ring or something that informs the user that something is going on and may have some progress updates. When a user navigates to a view where they can edit an entity, typically, it means that a form is displayed with a number of input controls, when the user hits save there is a validation of the data that has been introduced. If the data is valid then the entity is saved, otherwise a list of error is shown. The user experience is poor in this case. Whenever a user wants to see whether their input is valid, they need to click on save. From a behavioral point of view, the view is going through several states. It starts off in the editing state where the user is free to provide input. When the save button is clicked, the view actually first transitions into a validating state and depending on the outcome of the validation it either transitions into a saving state or transitions to an invalid state. If the application were to be implemented synchronously, which offers a lesser user experience, all these states are implicit and the view does not require any kind of modeling since the sequence of transitions is quite simple with two possible outcomes. On the other hand, if the application is written using asynchronous programming in an effort to provide a rich user experience, then having an implicit state machine may prove confusing and less maintainable. After a developer would investigate a bit the view, it would most likely become clear that there is a state machine at play even though it is implicit. [10] As the view transitions from one state to another the user interface needs to update. Some actions can be performed while in a state but cannot be performed while in another. [10] It is clear that there is need to model the state machine behind a view, but how does it fit with the View-Model-ViewModel pattern? The data has already been isolated from view models, leaving
  • 18. Interactive Applications in .NET - Architectural Approach 18 them open only to resembling behavior. Where better place would there be to implement a state machine? After all they are used to model behavior in software systems. [11] A Mealy Machine is a finite-state machine that uses both its input and its current state to determine its output. They can be used to model asynchronous reactive processes and, as with most if not all finite state machine models, it focuses on observable inputs and outputs. [12] In case of a view model which is an implementation of a Mealy Machine, further referred to as an interactive view model, operates based on a context which resembles the input and sometimes even the output as properties of an object may be set by the view model. [12] Depending on its current state and context, the interactive view model may transition to one state or another. If, for instance, the operation that is being carried out is a save operation then the output of the machine is the successful storage of the entity. [12] Commands that are exposed by an interactive view model can be bound to states that it defines. When an interactive view model transitions from one state to another, the commands it exposes automatically update. In other words, they raise the CanExecuteChanged event which in turn will make the control that has bound to the respective command call CanExecute(object) method. The method itself encapsulates the logic for verifying whether the command is bound to the current state of the interactive view model or not. An interactive view model should always expose a state, even if it is a state that is used to expose that behind the scenes, an operation is actually performed. When an operation finishes, depending on what requests have been received in the meantime and the context of the machine, the interactive view model will make another transition. It becomes obvious that states can be grouped into two main categories. Action states and quiet states. Actions states are states in which the interactive view model is carrying out a request. It is executing an asynchronous operation. Quiet states, on the other hand, are the typical states in which the interactive view model exposes some commands that are available to the user. In these states, the application is quietly waiting for user input. Initially, an interactive view model can be in either an action state or a quiet state, but whenever it enters an action state it should eventually transition to a quiet state unless an endless loop of operations is carried out. This is just a guide line, there are exceptions. For instance, a pooling loop can be implemented using action states. There is a pooling state in which information is being fetched and presented to the user, and afterwards there is a waiting state. The interactive view model will stay in the waiting state for a fixed period of time and afterwards will transition back into the pooling state. The waiting state it actually is an asynchronous operation that is implemented using Task.Delay(int) or Task.Delay(TimeSpan).
  • 19. Interactive Applications in .NET - Architectural Approach 19 Even though it may seem simple, one must take into account that it is possible that the fetch to fail due to losing Internet connection or a timeout on the other end. For situations such as these, the application can have a number of attempts to fetching data. If they all fail, then the interactive view model should transition to a quiet state where the user is asked for further instructions. If action states perform that actual operation, then what would a command really do? This is really simple. The commands that are exposed by an interactive view model actually resemble transition triggers for the view model that exposes them. Furthermore, the command can be bound to specific interactive view model states which will make them available based on the current state of the interactive view model that exposes them. When a command is invoked it will actually trigger a transition inside the interactive view model which in turn will update other commands and also start the desired operation. Any button that was bound to a command exposed by the same interactive view model will get an update. The will become available or disabled with respect to the current state of the interactive view model. Another issue, which was previously raised, is overlapping asynchronous operations. If a command is actually a transition trigger, then what would happen if the interactive view model is currently in an action state and a command that triggers a transition is invoked? Regardless of what initiates the transition, whilst in an action state, an interactive view model cannot transition to any other state. Any attempt to do so will result in an InvalidOperationException. The interactive view model can carry out one operation at the time, this does not block signaling cancellations and it does not block making changes to its context. When the context has changes, the interactive view model must react accordingly. Blocking transition requests while in an action state, in certain situations, forces the developer to find a work around this restriction that would only end up in code duplication. For instance, when the interactive view model is in the validating state and a change to its context occurs by user interaction, the interactive view model should automatically cancel the validation and start over as the data is currently validating is already outdated. To answer to this strictness, the interactive view model allows queuing transition requests. When a transition is queued the interactive view model will perform the transition if it is in a quiet state, if not then it will transition as soon as it enters a quiet state. The queueing mechanism resolves the validation problem, and probably others as well. If the interactive view model is already validating, then queueing another transition to the validating state seems appropriate as the same operation needs to be carried out all over again. Since action states resemble actual operations, it does not make sense to have an external event dictate how many times the interactive view model needs to queue state transitions. The response to the event is that the interactive view model will transition to the desired state at some point in the future if not immediately. If a request to queue a transition matches the last in the queue, then
  • 20. Interactive Applications in .NET - Architectural Approach 20 it is ignored. By this, if there are multiple changes to the context, thus multiple transition queue requests, there will only be at most one queued transition request towards the validating state. Clarifying thus far, the initial approach towards Model-View-ViewModel was to have a view model that provides properties for both data and commands that a view could bind to. In an effort to decrease costs and make code more reusable, the view models no longer expose data directly through its properties, but rather expose a context property which refers to an actual domain object. The view model implements a Mealy state machine behind the scenes in an effort to model its behavior in an explicit and clean way. Commands exposed by the interactive view model are actually triggers to transitioning to one state or another. These triggers can also queue transitions. 3.4.Validation Thus far only data and behavior has been covered. One important thing within software applications is validation. Validation is the act through which a set of data is checked in order to determine whether it conforms to a number of rules. Validation can be of multiple forms such as user input validation, schema validation, whether a product meets the requirements of a user and so on. Previously it was presented that domain objects should contain only data and that they should also be observable so they could be used directly by a view in an effort to avoid duplicate code and reduce the responsibilities of a view model. Continuing with the same idea, where should validation take place? More specifically, where should user input validation take place. A common way used through web applications built with ASP.NET MVC is to annotate models with various attributes, such as RequiredAttribute or EmailAddressAttribute which can be used to validate an e-mail address, that specify what kind of validation should be carried out on them. In case the attributes do not suffice, one can always implement ValidationAttribute and perform any custom validation that is required for a property, in case there is a requirement for which multiple properties must be involved or the value of one property determines the validity of another then one must implement IValidatableObject interface and provide custom validation in the implementation. This approach eliminates any layer dedicated for validation, however it imposes that the model itself should validate itself or at least specify what makes it valid. Both validation and data representation fall unto one class. [6] Besides, the same models can be used with an Object-Relational Mapping framework, such as Entity Framework, in an effort to simplify queries and data storage. The same class may end up being responsible for representing data, validating that data at a given point in time and also specify how it is stored in a relational data base. [9] As previously said, validation is of multiple kinds and they are treated differently. For instance, user input validation is a kind of validation that results in collection of error messages, preferably
  • 21. Interactive Applications in .NET - Architectural Approach 21 localized so they can be displayed in multiple languages, which is then displayed to the user. Schema validation where a given object is stored to a data store, any store not just relational, does not return a collection of error but throws exceptions. If a given object does not conform to the database schema, then there is most likely a programmatic error. Throwing an exception is the reasonable thing to do as it signals an abnormal situation. Constraints come from multiple sides, domain constraints are set by domain experts which also have a big part to play in developing the domain model. [8] There are also schema constraints, such as how many characters can a string contain, whether a field is an integer or a real number, a Boolean value and so on. Schema constraints are only set at the storage level, they may bring some restrictions to the domain model itself and the two may also overlap. When the two do not overlap it is better to bring domain constraints into the schema constraints only if they do not impact performance. Having this in mind, it is time to reflect this on the design thus far. Moving validation outside of the model itself means that there is a new component having this responsibility. The view model cannot be used to also contain domain validation as it is already responsible with managing a state machine. [11] The validation component will be responsible with validating a given domain object and providing a list of errors where the error message is preferably localizable. This increases reusability as the same type of object can be validated from multiple perspectives. There can be multiple validators that validate the same kind of object but having different logic encapsulated within them. Through this approach the domain objects can be used, as they are, by repositories. When retrieving an object from a repository one can always execute the validator in an effort to ensure that whatever the repository retrieved is valid from the point of view of the domain. Besides, data representation is separated from its validation. It is true that there is a dependency relation from the latter towards the former, however having them separated increases testability. One can write unit tests just for domain validation logic without having to change the domain model representation. Wrapping it up, after analyzing a few alternatives that seem to be paying off the initial Model- View-ViewModel approach has changed slightly (see figure 3).
  • 22. Interactive Applications in .NET - Architectural Approach 22 FIGURE 3 DECOUPLED MODEL-VIEW-VIEWMODEL ViewModel <<binding>> <<property changed notifications>> Model View <<provides data>> <<changes>> <<property changed notifications>> Validator <<validates>> <<uses>> <<binding>> Clearly, there are more dependencies this way, however the initial approach did not take into account multiple aspects of an application. There are two binding sources now for the view, the view model and the model itself. The former provides commands, which encapsulate behavior, to the view while the latter provides data to the view. In case of the model, there is also the possibility of two-way binding as user input needs to make its way to the model so it can be validated. Notice that there is no association between the view and the validator. It falls under the responsibility of the view model to validate the model; however, this behavior is delegated to a validator class which provides the view model with a collection of errors. The view model simply exposes this collection as an observable one thus the view will be automatically notified when it changes. Validation should be triggered automatically when a change to the model is made, such changes mainly happen through user interaction as the model is mainly updated through a two- way binding. Thus far, the overall architectural approach is decoupled, behavior is separated from data structures. The classes representing data may be reusable as they only provide a number of properties with specific data types and nothing else. Validation logic is testable and any change in the respective logic does not affect the domain model, unless the latter was designed wrong in the first place. The view model represents a state machine containing quiet and action states. Commands, which are provided by the view model, are bound to specific states making the available in some states and not in others. The view automatically enables and disables buttons based on the availability of the command they are bound to. [11]
  • 23. Interactive Applications in .NET - Architectural Approach 23 3.5.Visual State Manager So far, the only user interface interaction that was presented was enabling and disabling buttons through a command. That is hardly an interactive application as there is a lot more to this kind of applications than buttons. On the other hand, the part that was presented thus far is critical to a functioning application. Besides having a rich user interface, it is important to have functional software and most importantly to be able to write it with ease and at speed. Rich user interfaces have nice animations; controls update their visual aspect depending on what the application is doing in the back or whether the device on which the application runs is turned or moved. Animations have been a difficult thing to do since there is not always support from the underlying framework for them. Starting with XAML this has changed. Both Windows Presentation Foundation and WindowsRT have built-in support for animations and even offer a handful of predefined animations for the developer to use. A control may define for itself and contained controls a number of visual states. Each visual state is contained in a visual state group. A control may be in at most one visual state in each group. This means that the control may be in multiple visual states at the same time, but only at most one per visual state group. For instance, a number of controls define a visual state group for the orientation of the device. For each possible orientation, landscape or portrait, the visual state group contains visual states. When the user rotates the device, the visual state is updated and thus the visual aspect of the control is updated. Depending on the type of control they may display more information, or they may just expand to fit the available space after it was updated through the device rotation. Each visual state contains a set of instructions on how the control should transition to the respective visual state. It contains a declarative description for animations. Start values may be specified, but if omitted the current values of the respective property are used. This is useful as this allows the visual state to practically be able to transition smoothly from any other visual state. If, for instance in the middle of an animation another visual state transition is triggered, then the currently executing animation is stopped and the one specified by the latest visual state transition is started. Since start values can be omitted, the animation can still execute smoothly without having controls having sudden visual changes which are unpleasing. The entire visual state definition and transition is done through the Visual State Manager. This class is responsible for housing visual states for each control and making visual state transitions available to the developer in code-behind. Since the view model transitions from one state to another depending on what it is asynchronously doing behind the scenes, the view needs to update itself the same way. The view
  • 24. Interactive Applications in .NET - Architectural Approach 24 model is always in a state, there is no such thing as “transitioning”. The view model exposes its current state through a State property. Whenever the state changes a PropertyChanged event is fired by the view model so the view is notified of the changed. For each view model state, the view may define for itself visual states. When the view model changes its state, the view will transition to the visual state having the same name. Visual states contain specifications for how the control, or contained controls, should animate for this change. This makes them perfect for adjusting any visual aspect to illustrate that the application is working behind the scenes. Besides having buttons enable and disable when a view model transitions from one state to another, the view can now properly adapt to this change and update any control on the interface to illustrate the change. For instance, when the view model transitions to the saving state, the view may fade out all user input controls and fade in a process ring which shows that the application is currently saving the entity. When the view model completes the save, it will transition to the editing state while the view will fade out the process ring as the application is no longer processing and fade back in the user input controls. Figure 4 illustrates a simple interaction using a sequence diagram. [13] FIGURE 4 SIMPLE INTERACTION :UI saveCommand :TriggerCommand :EntityViewModel :Repository Execute(null) TransitionToAsync("Saving") <<event>>PropertyChanged("State") SaveAsync(entity) <<event>>PropertyChanged("State") <<tap>> save <<visual state transition>> <<visual state transition>>
  • 25. Interactive Applications in .NET - Implementing the Machine 25 4. Implementing the Machine Thus far there was mostly, if not only, design ideas. How would the ideas presented previously would actually be implemented? Is it even feasible? Starting with one of the most critical parts of the library, implementing INotifyPropertyChanged. Binding relies on it in order to update the content of a control. Since the interface only exposes one event, PropertyChanged, it is relatively easy to provide a default implementation. One of the goals of the default implementation is to simplify how the event is raised. As with all .NET events, raising one requires to invoke the backing delegate of the event with both the initiator of the event, referred to as sender, and an EventArgs, or one of its derivatives. For the PropertyChanged event the argument is represented by PropertyChangedEventArgs. To create one such instance one must provide the property name that has changed. This makes it relatively easy to abstract. The default implementation should expose a protected method that takes as argument the name of the property. The method itself constructs the PropertyChangedEventArgs instance and uses it to properly raise the event. Since the method is protected, the only way to access it from a different class is through inheritance, this solve the problem regarding the sender of the event as the initiator is the instance itself. Using the this keyword and the property name parameter the method has all the information required to raise the event accordingly. Providing the name of the property as a hardcoded string may yield problems when renaming them. The rename function within Visual Studio does not change hardcoded strings that contain the same value. If a property is renamed, then all places where it would be used to raise the PropertyChanged event also need to be updated. To solve this problem one can use the nameof operator available with C# 6.0, in case of using an older version for various reasons, one can use the CallerMemberNameAttribute and have the compiler fill in the property name automatically. Having a base implementation that makes it easy to notify upon property changes makes it ideal for a candidate for a base class to domain objects. Since they should be observable such that controls can be bound directly to them they should all derive from the default INotifyPropertyChanged implementation. Calling the protected method with the property name to notify that it has changed leads to a lot of copy and paste code which tends to become less challenging. If this becomes an issue or a lot of unit tests need to be written in order to test whether the event is raised with the appropriate property name, there are a few alternatives to remedy this. If unit tests become a problem, then one can write a generic unit test class and rely on reflection to test each and every public property that when it is updated the PropertyChanged event is raised with the appropriate property name.
  • 26. Interactive Applications in .NET - Implementing the Machine 26 If calling a method in each property becomes problematic then one can rely on Aspect Oriented Programming and use PostSharp, or any other tool, to have INotifyPropertyChanged automatically implemented by all types matching a pattern, such as all classes that are in a specific namespace. This technique will speed development time a little, but all the observable behavior that is required will be provided out of the box by any domain object without any additional code. Besides domain objects, there is the interactive view model. Any derivative of the InteractiveViewModel class should be able to define a number of action states in which the view model processes something. Each action state actually maps to a method that can be either synchronous, for quick operations, or asynchronous. The view model can be in exactly one state at a time which is either a quiet state or an action state. The name of the state is resembled through a string which allows it to be just about any value except null. Within the view model constructor, the user needs to make sure to transition to an initial state. If the state of the view model is queried before it actually transitions to one the State property accessor will throw an InvalidOperationException as the view model was not properly initialized. At any given point, action states can be created using a string as the name of the state, state names are case insensitive, and an associated method that performs the actual action. For reliability, it is best that all action states are created in the constructor, this will ensure that all action states are defined when the instance is made available. When an interactive view model transitions to a state which was previously marked as an action state, the mapped method is executed. Before actually invoking the method the state of the interactive view model is updated in the same sequence and not at a later point in time. This means that when calling TransitionToAsync, the view model will update its state accordingly before returning control to the caller. Figure 5 contains a sequence diagram illustrating the interaction happening when transition from one state to another. [13] The method starts by checking whether the state that the interactive view model should transition to is an action state. If that is the case, then the state is updated and all subscribers to the PropertyChanged event are notified of the change. The first callbacks that get executed are those that subscribed to the event and only after that the callback mapped to the action state is executed! This is very important as the user interface can be informed of the transition before actual execution is performed thus it can be updated accordingly. Each method mapped to an action state must have one parameter of type ActionContext which represents the context in which the action is being executed. One can query the action context to determine the source state from which the interactive view model transitions and use it to determine the next state. Before the mapped method or callback completes, it must provide the name of the next state the interactive view model should transition.
  • 27. Interactive Applications in .NET - Implementing the Machine 27 Instead of mapping the destination state of an action state when it is created it is provided by the callback to the view model after it has executed. This offers great flexibility as based on what happens within the action state the interactive view model can transition to one state in some cases and to a different state in other cases. At the end the state of the view model is updated with the latest state name returned through the ActionContext instance, in case there were any action states, or the state which was initially provided as parameter to the TransitionToAsync method. One important note is that an action state is not constrained to the kind of destination state it must provide. An action state may have as destination another action state which will result in a chaining of actions. All these transitions are visible to the interface and depending on the currently executing action the visual state may alter how controls are displayed. FIGURE 5 TRANSITIONTOASYNC INTERACTION :InteractiveViewModel TransitionToAsync(state) viewModelState: ViewModelState while [TryGetActionState(state, out viewModelState)] Property Changed Subscriber actionContext: ActionContext <<create>> <<set>>State := state NotifyPropertyChanged("State") <<notify>> <<await>>Execute(actionContext) <<awaitable Task>> <<set>>NextState := nextState <<continuation>> state := <<get>>NextState <<set>>State := state NotifyPropertyChanged("State") <<notify>> <<task completion notification>> One of the constraints that is not illustrated in the diagram in Figure 5 is that while an interactive view model is in an action state, any attempt to call the TransitionToAsync method will end in an
  • 28. Interactive Applications in .NET - Implementing the Machine 28 exception. In order for the interactive view model to transition to an action state it must either be in a quiet state or the action state itself to be in initial state of the view model. Since an interactive view model cannot be triggered to transition from one state to another while in an action state it would be useful to be able to queue transition requests. Behind the scenes, the view model stores the task which resembles the asynchronous execution of the last transition. To be able to queue transition requests one would need to await the previous transition task and only then make the request for the next transition. Note that the task returned by TransitionToAsync only completes when the interactive view model reaches a quiet state! This behavior needs to be maintained even for queued transition request. When calling EnqueueTransitionToAsync the method should return a task that will complete only when the transition towards the enqueued has completed. Figure 6 illustrates this. FIGURE 6 ENQUEUING TRANSITIONS interactiveViewModel: InteractiveViewModel EnqueueTransitionToAsync(state) <<await current transition>> <<await>>TransitionToAsync(state) <<task completion notification>> Most, if not all, applications have to do with user input. Thus far the interactive view model is only concerned about implementing the asynchronous model through a state machine. This is ideal for a base class for interactive view models as the entire logic of transitioning and queueing transition requests is all in one class and that class has no other responsibility. [11] This increases code reuse and reliability as the InteractiveViewModel class has only one responsibility which can be thoroughly analyzed and tested. The next step is extending the class to work within a data context. Previously it was mentioned that domain objects themselves should be observable and that they should be the data context in which a view model operates. While this may seem easy at first, there is a catch. When working with user input one must always validate that input. The rule still applies to interactive view models. The class containing the core
  • 29. Interactive Applications in .NET - Implementing the Machine 29 functionality cannot be simply derived and have an extra property holding the data context. The derivative must provide a way that alongside data, validation errors are also provided. XAML allows to specify the data context of a control through the DataContext property. Any binding expression made on the respective control will look at the object set through the DataContext property if a source is not specified. The intellisense is smart enough to know this meaning that once a DataContext is set one can use auto complete to browse through the list of available properties to bind to. Since there is only one DataContext property, in order to provide both data and validation errors to a control in order to bind to them, they must be packed into one object and the respective instance to be used as the DataContext of data bound controls. The type of the object housing both data and context is called ViewModelContext. It is not prefixed with “Interactive” since it may be used in other view models that are not interactive. It contains a reference to an object (it can be an object but as discussed previously, it would make sense to be a domain object) and a reference to a read only observable collection containing items of type ValidationError. ValidationResult from ComponentModel is not portable. The ViewModelContext class is generic as the object containing data can be of various types, even though binding would work even if the type of the property used in binding is of type object, it would be best to not limit intellisense where there is no reason to do so. The InteractiveViewModel which operates with a data context receives on the constructor a data object, which is generic, and provides to the ViewModelContext the same object and a read only observable collection proxy to a usual observable collection. This is to restrict the ability to edit the list of errors from outside the view model. [14] The observable collection of errors and the data object are exposed as protected properties which makes them only available to derivatives. This way, any interactive view model is able to manage the list of errors in their own way. Figure 7 illustrates the static structure of the components using class diagrams. [13]
  • 30. Interactive Applications in .NET - Implementing the Machine 30 FIGURE 7 STATIC STRUCTURE InteractiveViewModel #CreateActionState(name : string, action : Action<ActionStateContext>) #TransitionToAsync(name : string) : Task #TransitionToAsync(name : string, parameter : object) : Task #EnqueueTransitionToAsync(name : string) : Task #EnqueueTransitionToAsync(name : string, parameter : object) : Task #BindCommand(command : ICommand, states : string[*]) : ICommand #GetTransitionCommand(state : string) : ICommand #GetEnqueuingTransitionCommand(state : string) : ICommand #GetTransitionCommand(state : string, errorHandler : Action<ErrorContext>) : ICommand #GetEnqueuingTransitionCommand(state : string, errorHandler : Action<ErrorContext>) : ICommand #CreateActionState(name : string, asyncCancellableAction : Func<ActionStateContext, CancellationToken, Task>) #CreateActionState(name : string, asyncAction : Func<ActionStateContext, Task>) TDataModel InteractiveViewModel +<<create>>(dataModel : TDataModel) #<<get>>DataModel : TDataModel TDataModel ViewModelContext +<<get>>DataModel : TDataModel ValidationError +<<get>>Message : string +<<get>>MemberName : string #Errors : ObservableCollection<ValidationError>* +Errors : ReadOnlyObservableCollection<ValidationError> * +Context1 ErrorContext +<<get>>CanTransition : bool +<<get, set>>NextState : string +<<get>>FaultState : string +<<get>>IsCancelled : bool /+<<get>>Exception : Exception +<<get>>AggregateException : AggregateException InteractiveViewModel1 ActionStateContext +<<get>>Parameter : object +<<get>>NextState : string InteractiveViewModel1 +<<get>>PreviousState : string As it can be noted, there is an ErrorContext class. Commands have no returning type (void) thus they cannot be awaited but can be asynchronous methods. In order to be able to handle errors that may happen during the execution of a trigger command, an error handler callback can be
  • 31. Interactive Applications in .NET - Implementing the Machine 31 provided to the GetTransitionCommand method. This method creates a command that when executed it will trigger a transition towards the state given as parameter to the method. If the method execution fails in an exception, cancellation is also reported as exception, then the provided handler is used to remedy the situation and stop the application from crashing. Within the error handler one can check whether the exception that occurred was actually a completed cancellation or if something bad actually happened. Based on its logic, the error handler instructs the interactive view model to what state it should transition. The BindCommand method simply wraps the provided command into a proxy which allows the command to be made available only when the interactive view model is in one of the bound states. Ultimately it is up to the wrapped command to tell whether it is truly available in a bound state or not through its CanExecute method. [14] 4.1.Reactive Extensions Reactive Extensions is a library which also helps in developing interactive applications, however they do not rely on INotifyPropertyChanged interface, but more on IObservable and IObserver interfaces. Sadly, controls on the user interface do not respond to notifications from objects implementing these interfaces, however Reactive Extensions make use of observable collections. One can use this library to create asynchronous data flows using collections and queries. This is particularly useful at the view model level as data which is provided by the user can be used to filter collections asynchronously. The application will show results as they become available and not all at once. The approach presented in this paper does not cover data queries and how they should load on the user interface, however with Reactive Extensions one can bind the two and achieve a rich user experience with ease. The two can complement each other and neither is a replacement for the other.
  • 32. Interactive Applications in .NET - Conclusions 32 5. Conclusions This paper has presented an architectural approach towards developing applications in general, but more centered around being able to create rich user interfaces with tools that are already available. The originality of this work is illustrated through the implementation of a library that blends in with the .NET Framework and can be easily integrated, even partially, in any application. The library uses abstractions provided by the underlying framework without introducing any new ones that require workarounds in certain scenarios. The library itself is an extension of the framework not only using its abstractions but also promoting language features available in both C# and Visual Basic .NET, the library bridges concepts and tools in an effort to ease the creation of applications that provide a rich user experience by using asynchronous programming and eliminating data races that tend to happen in applications that use worker threads instead.
  • 33. Interactive Applications in .NET - References 33 6. References [1] R. C. Martin, The Clean Coder: A Code of Conduct for Professional Programmers, 1st ed., Prentice Hall, 2011. [2] J. Albahari and B. Albahari, C# 5.0 in a Nutshell: The Definitive Reference, 5th ed., O'Reilly, 2012. [3] A. Davies, Async in C# 5.0, 1st ed., O'Reilly Media, 2012. [4] J. Smith, "Patterns - WPF Apps With The Model-View-ViewModel Design Pattern," MSDN Magazine, vol. 24, no. 2, pp. 72-83, February 2009. [5] E. Gamma, R. Helm, R. Johnson and J. Vlissides, Design Patterns: Elements of Reusable Object-Oriented Software, Pearson Education, 1994. [6] Microsoft Patterns & Practices Team, Microsoft® Application Architecture Guide (Patterns & Practices), 2nd ed., Microsoft Press, 2009. [7] R. C. Martin, Clean Code: A Handbook of Agile Software Craftsmanship, 1st ed., Prentice Hall, 2008. [8] E. Evans, Domain-Driven Design: Tackling Complexity in the Heart of Software, Addison Wesley, 2003. [9] V. Vernon, Implementing Domain-Driven Design, 1st ed., Addison-Wesley Professional, 2013. [10] E. Burris, Programming in the Large with Design Patterns, 1st ed., Pretty Print Press, 2012. [11] V.-S. Tarquin, "MVVM - WPF Commanding with the State Machine Pattern," MSDN Magazine, vol. 29, no. 11, pp. 58-61, November 2014. [12] G. H. Mealy, "A Method for Synthesizing Sequential Circuits," Bell System Technical Journal, p. 34: 5, September 1955. [13] R. Miles and K. Hamilton, Learning UML 2.0, O'Reilly, 2006. [14] E. Freeman, B. Bates, K. Sierra and E. Robson, Head First Design Patterns, 1st ed., O'Reilly Media, 2004.