Saturday, May 18, 2013

A WCF Client of a RESTful service - XML

Version 1.0.0.68 introduces WCF support. This allows you to write a WCF client of a REST/XML service. We will add JSON support in a future release.

While this article includes code snippets only, the full code sample is included with dot42. Install dot42 and then open the sample from [MyDocuments]\dot42\Samples\Network\WcfTodoService. The solution includes both a server (project TodoServer) and a client (project ClientApp).

Compile and run the server

The server is a Windows application. It can be found as project TodoServer in the WcfTodoService solution. Compile this app and run it with administrator rights. When you run it, it shows the following dialog:


Start the service by hitting the 'Start Service' button. If you did not start the service with admin right, it will show you the following error:


To start with admin rights, compile the project and navigate to TodoServer.exe in folder \Network\WcfTodoService\Server\bin\Debug. Right-click the executable and select 'Run as administrator'. When you start the service, you should now see this:


The service uses port 9222, so make sure your firewall allows connections to it.

Shared files

The client and the server projects share the following files (these are in the WcfTodoService\Shared folder):
  • TodoApi.xsd
  • ITodoApi.cs
  • TodoApi.cs (auto generated from TodoApi by xsd.exe)
TodoApi.xsd and ITodoApi.cs together make up the API specification of the REST service. ITodoApi.cs is the service contract file. It defines an interface and has WCF attributes applied. TodoApi.cs is generated using the following command:
xsd.exe /c /n:Dot42.TodoApi.Version_1_0 TodoApi.xsd
This generates classes from TodoApi.xsd that provide a rich object model for regular XML data.

Client

The client is a dot42 project and will run on your Android device. The UI code is really straightforward and in order to focus on WCF, we will skip it and discuss the code that invokes the service.

The programming model is exactly the same as with traditional WCF, except that one option in the project properties has to be checked. With this option checked, dot42 will generate proxy classes for the service so there is no need to generate code at runtime.


All WCF client code in MainActivity.cs use WebChannelFactory to open a channel to the service and make requests to the underlying methods exposed by the contract:
private const string _hostAddress = 
  "http://192.168.1.1:9222/RestService/TodoService";

private VersionType GetVersion()
{
  using (var client = new WebChannelFactory<ITodoApi>(
    new WebHttpBinding(), new Uri(_hostAddress)))
  {
    client.Open();
    var channel = client.CreateChannel();

    using (new OperationContextScope((IContextChannel)channel))
    {
      return channel.GetVersion();
    }
  }
}
If you run the client on your Android device it will look like this:

The full code

While this article includes code snippets only, the full code sample is included with dot42. Install dot42 and then open the sample from [MyDocuments]\dot42\Samples\Network\WcfTodoService.

Friday, May 17, 2013

Integrating dot42 with SharpDevelop

With this post, we share our experiencies with integrating dot42 with SharpDevelop (#Develop from here on).

What version?

First we had do decide what version of #Develop we wanted to integrate with. There were two choices: Version 4.3 is the current stable version and therefore the obvious candidate. Version 5 is the upcoming version and currently in preview state. Looking at the future, it made sense to choose version 5. However it is still in preview state and even though we believe it is already quite stable, we did experience several crashes. Also, we don't know when version 5 goes into beta or RTM so we decided to choose 4.3. We tested with both versions and we expect to quickly upgrade to version 5 once it has stabilized.

Custom build or stock version?

With an IDE like Visual Studio this is a simple choice because there are only stock versions and everybody uses those. #Develop, however, is open source so we may choose to do a custom build. Because we want to minimize the maintenance load on our team, the initial approach was to extend a stock version using the standard addin model of #Develop. Doing so we ran into several issues. Especially, extending the debugger forced us to change this approach. We still use the stock 4.3.1 code base, but we had to remove the debugger addin. We also decided to integrate the entire IDE into our own setup. This makes it easier for us to test our integration because we know the exact version and we avoid potential problems in the field with existing #Develop installations.

The dot42 addin

#Develop is a highly extensible platform. It consists of a small core that has a namespace tree and an addin system. An addin extends the functionality of #Develop. The namespace tree is used to extend all kinds of functions like menus, debuggers, project types etc. An addin is implemented by an xml file (.addin) and usually one or more assemblies. The addins are automatically loaded from the AddIns folder.

Parts of the dot42 addin is a dot42 specific project behavior (this is similar to a project sub type in Visual Studio). To add this project behavior, we had to write one C# class and include the following snippet in our .addin file:

<Path name="/SharpDevelop/Workbench/ProjectBehaviors">
  <Condition
         guid="{337B7DB7-2D1E-448D-BEBF-17E887A46E37}"
         name="ProjectBehaviorSupported">
    <Class
         class="Dot42.SharpDevelop.Dot42ProjectBehavior" 
         id="Dot42ProjectBehavior" />
  </Condition>
</Path>

This snippet registers a class (Dot42.SharpDevelop.Dot42ProjectBehavior) in the namespace tree under the well known path "/SharpDevelop/Workbench/ProjectBehaviors". The Condition element ensures that the dot42 project behavior is used only when the project has the sub type identified by the given guid.

Next to the project behavior, the dot42 addin contains a debugger, various "pads" (UI elements) for the debugger, menu items, XML editors and more. All of these are integrated into the #Develop platform using Path elements in the addin file.

What did we encounter?

The addin system and namespace tree make it easy to extend #Develop but it lacks an important feature: you cannot remove or alter existing elements. For example we wanted to remove several menu items that are added by the stock debugger addin. This is not possible. More precisely, we wanted to add an additional condition to those menu items so they would be hidden for a dot42 project subtype. This is also not possible. A solution to this problem would be to modify the stock addin files, but that was something that we wanted to avoid. We posted a suggestion the #Develop forum to extend the core of #Develop to make this easier in.

We ran into another issue. Implementing our own debugger was a matter of implementing the simple interface IDebugger as published by #Develop. However, the standard debugger UI (pads for running threads, call stacks, local variables, etc.) assumes that the current debugger is always of type WindowsDebugger. Even worse, the UI crashes if this is not the case. For this reason, we had to remove the stock debugger addin and build our own UI pads for threads, call stacks, etc.

Breakpoints were a lot easier. These are special kind of bookmarks and by just querying the BookmarkService we quickly found BreakpointBookmark. We could use it as is without doing anything special to toggle them in the UI.

To wrap up

It has been a pleasure to integrate dot42 with #Develop. After the many many many hours we spend digging through tons of COM interfaces that make up Visual Studio, it is an absolute delight to extend an IDE that is fast and has all the sources available.

Hopefully we can help the #Develop team to improve their platform.

Thursday, May 16, 2013

1.0.0.68 - What's new

To get the latest version, run "Check for updates" from the Device Center or download.

New: SharpDevelop integration

As of this release dot42 includes a SharpDevelop integration. This is an option of the setup.

The SharpDevelop integration consists of a dot42 project type, project and item templates, a debugger and a designer for simple resource files such as strings and menus (not the layout).

We support the same functionality in SharpDevelop as we do in Visual Studio except for IntelliSense with XML files. We will add this in a future release.

New: WCF client support

You can now build a WCF client of a REST/XML service. The programming model is exactly the same as with traditional WCF, except that one option in the project properties has to be checked. With this option checked, dot42 will generate proxy classes for the service so there is no need to generate code at runtime.

We have added a code sample (Network\WcfTodoService) that demonstrates this new functionality. Don't forget to consult the readme of this sample because some configuration is required to get the REST/XML service running and accessible.

We will add support for REST/JSON services in a future release.

Changed: Setup warns about missing Visual Studio

If you do not have Visual Studio 2010/2012 Professional installed, the setup will warn you and instruct you to install SharpDevelop.

Fixed: Various casting problems

Various casting expressions (e.g. long to byte) could cause verify errors.

Fixed: Various enum conversion problems

Some conversions from enum to number expressions could cause verify errors.

Fixed: Various import jar problems

Several (java) jar files caused problems either at import time, build time or runtime. These jar files include files for the OUYA console, Google mobile ads and Google services.

Fixed: Breakpoints and step behavior are not precise

Setting a breakpoint at a specific location did not always result in an actual break. Stepping through the code in the debugger also showed some unexpected behavior. All of this was related to an incorrect mapping between source code line numbers and dex instruction offsets. This has been fixed resulting in a much better debugging experience.

Fixed: Local variables have incorrect name in debugger

Local variables had numbers appended to their names while debugging. Now the original variable names are used. This also fixes the problem when hovering over a variable during debugging. It now shows the variable value as a tooltip.

Monday, May 6, 2013

C# Lambda Expressions

A lambda expression is an anonymous function that you can use to create delegates or expression tree types. By using lambda expressions, you can write local functions that can be passed as arguments or returned as the value of function calls. See Lambda Expressions (C# Programming Guide).

Lambda expressions are supported by the dot42 compiler. The Calculator code sample demonstrates the use of lambda expressions by creating handlers voor de button click events.


While this article includes code snippets only, the full code sample is included with dot42. Install dot42 and then open the sample from [MyDocuments]\dot42\Samples\Various\Calculator.

Handling the button click event

The click event of the add, subtract, multiply and divided buttons are all handled by the same method Calc but per button instance a different argument is passed:
protected override void OnCreate(Bundle savedInstance)
{
  ...

  btn = (Button)FindViewById(R.Ids.cmdAdd);
  btn.Click += (s, x) => Calc(Operations.Add);
  btn = (Button)FindViewById(R.Ids.cmdSub);
  btn.Click += (s, x) => Calc(Operations.Sub);
  btn = (Button)FindViewById(R.Ids.cmdMul);
  btn.Click += (s, x) => Calc(Operations.Mul);
  btn = (Button)FindViewById(R.Ids.cmdDiv);
  btn.Click += (s, x) => Calc(Operations.Div);
}

private void Calc(Operations operation)
{
  Calc();
  this.operation = operation;
  leftOperand = rightOperand;
  rightOperand = 0;
  FormatValue();
}
Note that without lambda expressions, you would either have to define a different method per button or the operation (+, -, *, /) would somehow have to be encoded in the event source.

Friday, May 3, 2013

1.0.0.67 - What's new

To get the latest version, run "Check for updates" from the Device Center or download.

Changed: Enum types are now implemented as instances.

Before this version enum types were implemented as their underlying primitive type. Typically, an enum was implemented as an int (value type). This has been changed. Now enums are implemented as object instances as in Java. The reason is that we could not distinguish between enum parameters and primitive type parameters. So both method Foo(int) and method Foo(MyEnum) were compiled to Foo(int) causing a verify error.
This change is handled by the dot42 compiler. It does not require any change in your code.

Improved: Device Center usability.

The Device Center has been simplified by removing the Home tab and removing all unnecessary ribbon buttons.

Improved: Many .NET framework members added.

Lots of .NET members have been added to existing types and new types have been added. This includes types in System.Net and System.ComponentModel.

Fixed: Java classes using SomeType<Void> cause verify errors.

In Java it is allowed to use Void as a type argument for generic parameters. This is not supported in C#. When a Java jar file is imported into C#, all Void type arguments are converted to Object.

Fixed: Nullable enum types cause verify error.

This has been solved as part of the above enum change.

Fixed: TearDown attribute on NUnit tests not supported.

The TearDownAttribute attribute has been added and is used as expected in NUnit test cases.

Fixed: Various minor compiler issues

Lots of small (often unreported) compiler issues have been fixed.

Coming soon...

We are getting close to releasing support for the SharpDevelop IDE.