NAVmoble - the pocket-sized ERP
Optimized for Microsoft Dynamics NAV and Windows Mobile powered devices

Sunday, December 10, 2006

True or False: The geek's quest for the golden hammer

I'm looking at me as a regular tech geek spending the most of my personal time to educate my self . I'm reading ,listening , attending ,arguing and blogging in my private personal march to the perfection.
Experts, blogs,podcasts, community sites, companies, journalists - all of them are arguing about the best methodology, technology and techniques. All of them are yelling that this or that is the silver bullet for my problems:



"So this week, we're introducing a general-purpose tool-building factory factory factory, so that all of your different
tool factory factories can be produced by a single, unified factory. The factory factory factory will produce only the
tool factory factories that you actually need, and each of those factory factories will produce a single factory based
on your custom tool specifications. The final set of tools that emerge from this process will be the ideal tools for your
particular project. You'll have *exactly* the hammer you need, and exactly the right tape measure for your task, all at
the press of a button (though you may also have to deploy a few *configuration files* to make it all work according to
your expectations)."
                                                                                                                                     Why I Hate Frameworks, BenjiSmith


And I'm in the center of all this madness! Alone with my geeky problems waiting to recognize the real panacea for my daily technical problems.
I'm into this everlasting quest for the golden hammer for quite a long time and actually this is what thrills me the most in my lonely geeky nights. I don't know actually what I like the most: the moment of feeling, that I found the silver bullet or the next day, when I'm realizing that my geeky quest will continue. We geeks are kind of explorers, arn't we! If we discontinue our exploration activities, we won't be explorers anymore.


I've got this moments, when I feel consistent:  I do not have doubts, I know exactly which tool or technique to use, I feel I'm following up all the new concepts around. And there are short moments, when I feel lost, tired and totally disoriented. This is the payoff for raping my brain with tons of information night after night.


Along with my nightly activities, It is not rare for me to answer to questions from other people around me. Often these are new "kids" in the industry, who think I know the answers of all questions.
And here comes my big personal question: TRUE OR FALSE?
I am spending a lot of time around my team's young devs and hence I get this kind of questions, when I doubt, what is the right answer. All these guys are trying to get a simple and straightforward answer - the answer of all answers. They ask:



  • Is the ORM approach better than the classic Table-driven approach. Why we use ORM, when in on CodeProject somebody said it is a doomed concept.

  • Why we have a 3  layers architecture. I've read on Channel 9 that the 4 layers architecture rules.

  • Why we are not using WCF, but classic Asp.NET Web Services. They all talk about WCF.

  • They said on DotNetRocks.com that  Rubby is so great,  but we are still using C#. Why?

  • Why we use Scrum?  My university teacher said that XP is better!

  • There is article on MSDN, which says that the future is in the Software Factories and we use some third party Code Gen products. Why's that?

  • Shall I use custom Service Locator implementation or using some light container implementation like Castle?

  • They said that Personal Social Number should never be a primary key in a table. Why we broke this global rule in our project?

TRUE or FALSE? What to tell these guys, who want to get a simple question to solve their problems. How to give them a simple answer, when there is only a long and complicated one. How to give them this simple answer, when the decisions are bound also to our specific political , business and culture context. They want all-time global and easy answers. This are the moments, when they are learning how to get decisions. Shall I tell them that (often) there is no global and absolute arguments. Shall I tell them that I just don't know for sure , but I think this way it will work just fine . TRUE or FALSE?  Telling TRUE may break their confidence in the industry, in experts  in practices. Telling them FALSE (by hiding some part of the truth) may gave them the wrong idea that this industry is like a religion:that it is all about idols and absolute true.


 


What do you answer in such situation? TRUE or FALSE?

Saturday, December 09, 2006

"How To" Series: Building a Signature Control in Compact Framework

It is not a rare requirement for a mobile application to provide functionality for capturing a person signature.
So, let's see if we can provide this feature into a mobile application with .NET Compact Framework.
The image bellow outlines the problem that we want to solve:



We have a mobile salesman, who collects customer orders. Our salesman should collect the customer's signatures along with the order's details. Our salesman is carrying a Pocket PC device. We should create
a software solution to allow customer's signature capturing and transmition of the signature over the wire to the office. There we have a Sql Server database to store the signatures into and signatures consuming app. , which may process the stored signatures.


We should solve the following tasks:



  1. Capturing a signature from a person from the mobile device
  2. Saving the captured signature locally on the mobile device
  3. Transmitting the saved signature over the wire and storing it on the server side
  4. Consuming the transmitted and saved signature on the server side

Let's try to solve these tasks:


Solving Task 1: Capturing a signature from a person on the mobile device


If a person should place its signature on a Pocket PC, he will probably use the stylus to write his signature on the Pocket PC screen. All we have to do is to capture the on-screen tapings and convert them into a bitmap. We will create a User Control to encapsulate this functionality. The main functionality is divided between the following UserControl event handlers:



  • OnMouseDown - here we will "remember" the coordinates of the last on-screen tapping
  • OnMouseMove - here we will draw a line from the remembered coordinates to the new(after the mouse move) on-screen mouse coordinates.


Following code example(simplified version)
...
private Bitmap SignatureImage;
private Graphics GraphicsHandle;
privte Point MouseCoords;
....
SignatureImage = new Bitmap(this.Width, this.Height);
GraphicsHandle = Graphics.FromImage(SignatureImage);
...
//remembering the coords of the last on-screen tapping into  MouseCoords member
protected override void OnMouseDown(MouseEventArgs e)
{
  base.OnMouseDown(e);
  MouseCoords.X = e.X;
  MouseCoords.Y = e.Y;
}
//draw a line from the remembered coords to the new on-screen tapping coords
protected override void OnMouseMove(MouseEventArgs e)
{
  base.OnMouseMove(e); 
  GraphicsHandle.DrawLine(SignaturePen, MouseCoords.X, MouseCoords.Y, e.X, e.Y); 
  MouseCoords.X = e.X;
  MouseCoords.Y = e.Y;

//saves the captured bitmap image into a stream
public void Save(Stream stream)
{
   SignatureImage.Save(stream, ImageFormat.Bmp);
}  


Solving Task 2: Saving the captured signature locally on the mobile device


This task is simpler. Let's pretend, we should save the captured image into a local SqlServer Mobile database.
We should have a table containing a field of type image to save the signature into it.



CRATE TABLE CUSTOMERSIGN
{


   customerNo:int not null identity
   sign:image
}


Following the code to save the captured signature:


//our signature control placed into a form
private
SignatureControl MySignatureControl;
...
string connectionString =  ...;
...
using (SqlCeConnection connection = new SqlCeConnection(connectionString))
{
  connection.Open();
  SqlCeCommand command = new SqlCeCommand("INSERT INTO CUSTOMERSIGN(sign)VALUES(?)", connection); 
 


  //getting the captured signature as stream
  MemoryStream signStream = new MemoryStream();
  MySignatureControl.Save(signStream);


  param = new SqlCeParameter("sign", SqlDbType.Binary);
  param.Value = signStream.ToArray();
  command.Parameters.Add(param);


  command.ExecuteNonQuery();
  connection.Close();
}
Now we have the signature saved locally...
We may save the signature into another storage type like a file for example.


Solving Task 3: Transmitting the saved signature over the wire


Usually the most valuable mobile applications provide functionality to send and receive data to/from some in-house systems running in the company's office.
Let's see if we can send the captured image back to the office over the wire. Although there are various communication options that may be used to transmit the signature over the wire, we will see only the Xml Web Services way in this article. Other possible options are TCP/IP transmition with sockets, Merge Replication,RDA  and why not E-mail .
First, we should create our Xml Web Service. This Xml Web Service will run on the company's office web server. The web server its self should be "http reachable" by  our PocketPC. So, when our Pocket PC device gets a network connection, it may invoke our Xml Web Service and send all the captured signs back to the office.
Let's have a similar table (CUSTOMERSIGN) created into a Sql Server, which also runs in our office. Our Xml Web Service will receive the captured signatures from the mobile app. and will save them into the CUSTOMERSIGN table in the Sql Server. Later another app. may fetch the stored signs to process them in some way.


The  Xml Web Service will have one web method like this:




[WebMethod]
public void TransmitSignature(int customerId, byte[]
signature)
{
  using(SqlConnection connection = new SqlConnection(connectionString))
  {
     SqlCommand insertCmd = new SqlCommand("INSERT INTO CUSTOMERSIGN(customerId,sign)VALUES(@customerId,@signature)", connection); 
     insertCmd.Parameters.AddWithValue("@customerId", customerId); 
     insertCmd.Parameters.AddWithValue("@signature",signature);
     insertCmd.ExecuteNonQuery();
  }


}


Then on the mobile side, we may create a web reference to our Web service and consume it, when a network connection is available


OfficeService.SignService signService = new OfficeService.SignService();
using(SqlCeConnection cnn = new SqlCeConnection(connectionString))
{      


        SqlCeCommand cmd = new SqlCeCommand("SELECT customerId,signature FROM CUSTOMERSIGN",cnn);
        SqlCeDataReader reader  =  cmd.ExecuteReader();
        while(reader.Read())
        {
            int customerId= (int)reader[0];


            //read the signature from the mobile database
            int imgSize = reader.GetBytes(1,0,null,0,0); 
            byte[] signImageData = new byte[imgSize];
            reader.GetBytes(1,0,signImageData,0,0); 


            //transmit signature over the wire
            signService.TransmitSignature(customerId,signImageData);
         }          


         //delete transmited signatures from the mobile database
         
SqCeCommand deleteCmd = new SqCeCommand("DELETE FROM CUSTOMERSIGN",cnn);
         deleteCmd.ExecuteNonQuery();
 } 


Note, that this example is not quite efficient from a performance point of view. It will be more performant to have a Web Method, which accepts
a collection of signatures at a time. It may be performed easily by using DataSet to fetch and  transfer the captured signatures:

[WebMethod]
public void
TransmitSignature(DataSet signatures
)

Solving Task 4: Visualizing the transmited signature on the server side


Once we have the captured signatures saved on the server side, we may need to consume them. For example we may want to show them as images on the screen.
In order to do this we should fetch them from the database:



//picturebox control to show the signature
private PictureBox pictureBox1;
...
int interestingCusotmerId;
 ...
SqlCommand cmd = new SqlCommand("SELECT signature FROM CUSTOMERSIGN WHERE customerId=@customerId", connection);
cmd.Parameters.AddWithValue("@customerId",interestingCusotmerId);
SqlDataReader reader  =  cmd.ExecuteReader();
if(reader.Read())
{
    //read the signature from the database
    int imgSize = reader.GetBytes(0,0,null,0,0); 
    byte[] signImageData = new byte[imgSize];
    reader.GetBytes(0,0,signImageData,0,0);
    //show the signature as Bitmap image
    using(MemoryStream ms = new MemoryStream(signImageData))
    {
      pictureBox1.Image = new Bitmap(ms);
    }
}          


The presented example is not a complete solution. It just outlines some of the common problems, which should be addressed if one needs to build a signature capturing solution. 
A real world solution may be far more complicated and should address a lot of problems not mentioned here. For example there are other signature capturing techniques ,which may store the signature in more compressed format. One may need to encrypt/decrypt the captured signature to protect it or validate the signature(biometric). Please see the links bellow for more examples.



Links:


Monday, December 04, 2006

WPF/E CTP is out

Microsoft released the first CTP for WPF/E.

“WPF/E” is the Microsoft solution for delivering rich, cross-platform, interactive experiences including animation, graphics, audio, and video for the Web and beyond. Utilizing a subset of XAML (eXtensible Application Markup Language)-based Windows Presentation Foundation technology, “WPF/E” will enable the creation of content and applications that run within multiple browsers and operating systems (Windows and Macintosh) using Web standards for programmability. Consistent with Web architecture, the XAML markup is programmable using JavaScript and works well with ASP.NET AJAX. Broadly available for customers in the first half of 2007, “WPF/E” experiences will require a lightweight browser plug-in made freely available by Microsoft.



The CTP contains the WPF/E plugin itself and SDK



There is a Macintosh version as well

Links:

WPF/E Downloads

WPF/E Dev Center

Sunday, December 03, 2006

Microsoft Days in Sofia University

I had a short presentation discussing the .NET Compact Framework goodies, during the Microsoft Days in the Sofia University
The Slides and the source code are available(in Bulgarian):
If you have any questions or troubles compiling the source code, please contact me at r underscore trifonov at hotmail dot com

Friday, December 01, 2006

"How To" Series: Detect network connection in Compact Framework

There is several ways to accomplish this and I will outline some of them in this post.


The following snippet may be used to detect if the device is connected to a network.
It checks if the device has an IP address assigned. This approach will not work properly if the device has a static IP. It is not guaranteed that a specific network destination is reachable.


bool IsConnected
{
    get
    { 
        try
        {  
            string hostName = Dns.GetHostName(); 
            IPHostEntry curHost = Dns.GetHostByName(hostName); 
            return curHost.AddressList[0].ToString() != IPAddress.Loopback.ToString(); 
        } 
        catch
        {
            return false; 
        }
    }
}


Another possible approach is to check if there is a "path" to a specific destination.


public bool IsNetworkPathAvailable(string destinationAddress)
{
     bool connected = false
     HttpWebRequest request;
     HttpWebResponse response;
     try
     {
          request = (HttpWebRequest)WebRequest.Create(destinationAddress);
          response = (HttpWebResponse)request.GetResponse();
          request.Abort(); 
          if (response.StatusCode == HttpStatusCode.OK)
         {
              connected = true;
         }
    }
    catch (WebException ex)
    {
        connected = false;
    }
    catch (Exception ex)
    {
       connected = false;
    }
    finally
    {
       if(response != null)
          response.Close();    
    }
    return connected;
 }
//here we will use the network detection
if(IsNetworkPathAvailable(http://www.ritsoftware.com"))
            SendSomeDataOverTheWire();  


Another way to accomplish this is to use the InternetGetConnectedState function from wininet.dll
[DllImport("wininet.dll")]
private static extern bool InternetGetConnectedState(ref uint flags, uint dwReserved);

public bool IsConnected
{
   get
   {
        uint flags;
        return InternetGetConnectedState(ref flags,0);
   }
}  


 


Links
ConnectionManager class from www.opennetcf.org
Compact Framework Newsgroups


 


 


 

Wednesday, November 01, 2006

WCF on the mobile side

Roman Batoukov has a post explaining in details the plans about providing Windows Communication Foundation support in the .NET Compact Framework.
The programming model provided will be limited to channel layer messaging only. It will be extensible, so the developers eventually will be able to implement their own transports. Few out-of-the box transport channels will be delivered like Http and E-mail.

Roman discusses some common problems regarding the devices communication , their solutions(when the WCF is out) and the feature of the E-mail as a messaging transport.

Read the full article

Sunday, October 29, 2006

More pictures from the DevReach Conference

Martin published pictures from the DevReach conference on his blog!

AJAX and Pocket PC

Having my Vista gadget from my previous posts(1,2), I decided to see if I'll be able to monitor the status of my Cruise Control.NET projects from my Pocket PC.

My Pocket PC is running WM2003 SE and hopefully it turns out to be possible.



PocketIE provides support for Ajax, however in order to run the javascript code from the CC.NET gadget some changes should take place:

  • All invocation to the SideBar Gadget API should be removed. It includes all System.Gadget.Settings.read and System.Gadget.Settings.write statements
  • The XmlHttpRequest instance creation should be done by creating an ActiveX object(See example bellow)
  • PocketIE does not support setInterval , so it may be replaced with setTimeout. It must be called again and again on every successful postback in order to get a similar behavior

The XmlHttpRequest instance may be created with the following code:


xmlHttp = false;
try
{
xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
}
catch (error1)
{
try
{
xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
}
catch (error2)
{
}
}

You may download the source code from here

Links:
Pocket IE and Ajax 1(IEMobile Team blog)
Pocket IE and Ajax 2(IEMobile Team blog)
IEMobile Team blog

Sunday, October 22, 2006

Vista Sidebar Gadget for Cruise Control.NET - Explained

My previous post was about my Vista Sidebar Gadget for Cruise Control.NET. Today I'll drop few lines about the gadget source code.
As you see on the diagram in the previous post, the gadget is making http requests to a home made xml web service in order to get the status of the projects registered in the CC.NET service. The requests are performed with the help of the XmlHttpRequest object. The javascript code looks like this:



1 xmlHttp = new XMLHttpRequest();
2 var url = System.Gadget.Settings.read("url");
3 xmlHttp.open("POST",url,true);
4 xmlHttp.setRequestHeader("Content-Type","text/xml");
5 xmlHttp.setRequestHeader("SOAPAction","
http://tempuri.org/GetProjectStatuses");
6 xmlHttp.onreadystatechange=HandleResponse;
7 xmlHttp.send(soapEnvelop);


This sinpset creates a fresh XMLHttpRequest instance and performs the web service invocation.

  • Line 2 reads the Url of the web service from the gadget's setting
  • Line 3 prepares the request. The "true" argument specifies that it will be an async request.
  • Line 6 passes a function to the XMLHttpRequest instance , which will handle the response from the web service, when available - that's because we are making an async request.
  • Lines 4 and 5 prepare Http headers to send with the request
  • and finally Line 7 sends the envelop

One may ask the following questions:

  • How do you know what the lines 3,4, and 5 should looks like?
  • What the content of the soapEnvelop variable should be?
In order to get the answers of these two questions you should browse the url of the xml web service(hopefully it is a .NET web service) .You will see the list of the methods(actions) provided by this web service:



Clicking the GetProjectStatuses method will bring the following screen:

This screen actually shows you what the 3,4 and 5th lines should contain. The first gray area shows what request should be sent. You just may copy the xml content provided and paste it in your source code. This is the content that should be placed in the soapEnvelop variable.

The second gray area shows what the response from the service looks like. It is obvious from the picture, that we will get a list of strings. So, we may use an Xml parser to navigate to the GetProjectsStatusesResult tag to extract its content.This is what the HandleResponse function does:



1 function HandleResponse()
...
2 var xmldoc = xmlHttp.responseXML;
3 var responseNode =
xmldoc.getElementsByTagName(
"GetProjectStatusesResult").item(0);
4 for (var iNode = 0;iNode <
responseNode.childNodes.length; iNode++){
5 var projectContent=
responseNode.childNodes.item(iNode).text;
6 var tokens = projectContent.split('|');
7
8 var imgTag=" ";
9 if(tokens[1]=="Success"){
10 imgTag=imgSuccess;
11 }else{
12 imgTag=imgFailure;
13 }
14 ...
15 }
...

    .
  • Line 1 gets the xml response from the web service
  • Line 3 locates the GetProjectStatusesResult tag.
  • Lines 4 through 13 iterates over the GetProjectStatusesResult tag children. Every children here contains the status of a particular CC.NET project



You may download the gadget's source code from here

Tuesday, October 17, 2006

Vista Sidebar Gadget for Cruise Control.NET

I am a Cruise Control.NET fan. I'm also playing with Windows Vista for quite some time and decided to create a Sidebar Gadget for Windows Vista to monitor my Cruise Control.NET enabled projects Although I've played with Sidebar gadgets before (see this post) this time is even more challenging as I'm not a Javascript geek. In general my goal was to duplicate the functionality provided by the CCTry. The CCTry application is intended to give developers to monitor the status of the projects registered into CC.NET. It also provides additional functionality ,which is out of the scope of my gadget. Actually the main reason to create this gadget was to play a little with a stuff like async web services invocation and xml parsing in he Sidebar gadget environment. So, first of all I had to decide what kind of communication scheme to use between my gadget and CC.NET Service. The CC.NET Service is running on machine other than my Vista box. As far as I know there are 2 basic communication options within the Sidebar Gadgets:
1. Making HTTP requests via XmlHttpRequest object
2. Using ActiveX objects
I decided to use the 1st option and then google provided me with this useful post about using CCTry managed API to communicate with the CC.NET service through .NET Remoting. I then quickly came with the following scheme:


The white squares are the components that I had to implement:
1. CC.NET Sidebar Gadget
2. CC.NET Xml Web Service
I've opened VS2005 and quickly implemented the CC.NET Web Service. I've implemented one method with the following signature:
[WebMethod]
public string[] GetProjectStatuses()

This method gets all projects and their statuses from the CC.NET Service by using .NET Remoting. It returns a string array (a string per registered project) then. The string contains the name of the project , its status and the CC.NET Dashboard url - all delimited by the | symbol.
Example:
My Project 1|Success|http://ccnetserver/ccnet
My Project|Failure|http://ccnetserver/ccnet

That was not quite elegant solution, but it was the shorter dev path :)
I've power up my Vista box then and soon I had my gadget running: The gadget displays a list of projects registered in the CC.NET Service. Green light means that the project is in good health and red means that the projects build is bad:

The gadget provides a settings dialog where the user may provide the CC.NET Web Service Url and time interval to poll the web service.


The CC.NET Gadget(and CC.NET Web Service) source code may be download from here.
Next time I'll blog about the CC.NET Gadget source code...stay tuned

Sidebar Gadget Links:
Vista Sidebar and Gadgets
Windows Sidebar team's blog
Daniel Moth blog

Thursday, October 12, 2006

DevReach conference just finished

The first DevReach conference just finished and I'm back to my daily (and nightly activities :) )
I really enjoyed this 2 days . I liked the drinks, I liked the food - what more you may want from a dev conference :)
The content was pretty cool. Although, I could bear sessions that dig into deeper tech. matters , I may say the content was good enough. The interesting part was the Q&A panel first day, which turns out to be a live .NET Rocks!.
There was I great foreign speakers and few local guys as well. I really enjoyed all the sessions of Ted Neward - unfortunately he had 3 sessions only. I also liked the cool and easy session of Carl Franklin about RSS, Podcasting, and Syndication - I've learn some simple and valuable tips that I had no time to learn before. And hey , he had I great trick with playing cards at the end of the session and I'm really waiting to see if Carl will publish the code for it! :)
I liked the session of Hirsto Deshev about Atlas. I think the session was quite hard for most of the audience , but it was just what I needed.

Links:
Check out this interesting comments from Carl Franklin
See this pictures by Julie Lerman
Check out some comments and pictures by Sahil Malik











Sunday, October 01, 2006

Rubby On Rails: WEBrick may fail to start if ActiveSync Connection Manager is running

I decided to spent some time playing with Ruby On Rails on my Windows XP box. I've downloaded the InstantRails and found some good starting points to create my first app. I found this great webcast from Matt Griffith. Everything worked fine until I had to start WEBrck and got an error message saying:


...
WARN TCPServer Error: Bad file descriptor - bind(2)
D:/Ruby/lib/ruby/1.8/webrick/utils.rb:73:in `initialize': Bad file descriptor -
bind(2) (Errno::EBADF)
...


Google said this error message may appear if WEBrick can't open port 3000.
Netstat showed that port 3000 is opened by process called "wcescomm.exe" and that is the process name of the Microsoft Active Sync Connection Manager.
I've just synced my PocketPC few minutes ago and the device was still in its cradle. I removed it from the cradle and tried again to start WEBrick ... I was so pleased to get it running.



Links:
InstantRails: one-stop Rails runtime solution containing Ruby, Rails, Apache, and MySQL
Getting started with InstantRails by Matt Griffith
Programming Ruby book
RadRails Ruby on Rails editor

Friday, September 22, 2006

Automated Acceptance Testing with Fitnesse,Selenium and .NET 2.0

I'm digging lately with my team into our new product. We are using a full stack of buzz words in our development like .NET 2.0, Atlas, WCF , etc... We are using SCRUM (at least that was the primary goal) to manage our dev process and some useful XP techniques to make our life easier.
The system that we are building is actually a general ASP.NET based application framework, which got it's own development tools.These dev.tools allow customization of the system on the customer's site. The dev. tools are intended for using by non-technical(at least none-geeks) people(consultants, distributors, customers).
In general the user functionality is organized in so called TASKS. Every tasks is a mini workflow consisted from a number of states(called STEPS) and transitions(called ROUTES). Every step may have a corresponding view (this is what the user sees) and every step and route may have attached a set of Code Units. A Code Unit is a sequence of actions coded via custom XML based language. The Code Units" actually are the logic that drives the application behind the scene.
Our first application to develop with this framework is a mass market HR solution and we intend to deploy it on few thousand sites during it's life cycle. We realized, that this highly customizable solution is about to cause us a serious maintainability related problems if managed in a traditional way. Our HR solution will be deployed and configured with a standard set of TASKS,CODEUNITS, VIEWS ,and other customizable objects. The standard set of customizable objects in the system may outnumber few thousand. After the solution deployment our customers receive updates of the product usually every 2 months(or even more frequent). One reason for this is the frequent changes in the legal regulations regarding the payroll law in our country. There are other reasons as well , however the main point here is that we'll have to update frequently a large number of product sites, which eventually will be customized in their own way. Every site will have a standard set of objects, but may also may have modified and fresh new objects as well. This forced us to design a simple and efficient business process to handle this issues, which I will not discuss here. Part of the solution for us is the use of Fitness and Selenium.
We are already TDD driven and using NUnit to do our unit testing. However we needed a tool to minimize the gap between our business analytics and our devs. While seeking for a solution I've found this article by Jeremy Miller. We've decided to use a similar approach.

After installing Fitnesse and Selenium on our build server, we've created a simple(and effective) "testing" language for our product. We wanted to have a live product spec. We wanted to have our standard set of TASKS defined by our business analytics described in a useful and simple language in our live spec document.

Following a simple example of a TASK defined:
This table contains a testable description of the normal flow of a task with identifier dps0001. The task is intended to allow entering of a new employee master record and it is consisted of 2 steps. The first step alows entering of the employee's social number and some dates. The second step allows entering some address information. There is one transition(Route navigation) between the two steps and one transition after step 2 to finish the task.
You may think of it like a story card for example. The good thing here is that you may have a bunch of natural language text here around the testable description



Start Taskdps0001
noteSTEP 1: EMPLOYEE GENERAL INFO
Set TextBoxSocialNo0 6603066766
Set DateTimeBoxBirthDate0 1.1.2005
Set DateTimeBoxIdCardIssueDate0 1.1.2005
checkNavigate Routenext false 
noteSTEP 2: EMPLOYEE ADDRESS
Set TextBoxCountry Bulgaria
Set TexBoxCity Sofia
Set TextBoxLine 1 Stara Planina Str. 41
checkNavigate Routesave true 
Stop

After starting the test, the table utilizes our special Fixture class (it inherits FitLibrary.DoFixture) called OmeksEntFixture. The OmeksEntFixture class mixes the Fit and Selenium functionality. It will perform few HTTP requests towards our testing server and hopefully the table will turn in GREEN to indicate that the story is already implemented .. OR... the devs will soon realize that there is another story that turns in RED and needs attention. The good thing here is that the implementation is already hard-linked with the spec (forever :) ) and our build process will never succeed until the story is not implemented as specified.
As we are using CC.NET as a build integration platform, we placed the Fitnesse/Selenium tests into our build process. It took us about 2 weeks to reach the moment to integrate our live and testable spec document with the set of the agile dev. techniques that we are using.

<COMERCIAL BLA BLA>

Now as we have this great tool for filling the gap between our business analytics, we will use this silver bullet to shoot all the problems and to deliver the project on time and within the half of the budget! :)

</COMERCIAL BLA BLA>



Links :
FitNesse Website
Selenium RC web site
Fitnesse and .NET - a basic tutorial
Create a Testing DSL with Fitnesse and Selenium
Automated Web Testing with Selenium Driven by .Net
How to integrate FitNesse acceptance tests into your CC.Net build
How to get FitNesse to switch to .Net mode
Some good posts on Fit, by James Shore

Friday, September 08, 2006

DevReach - The Premier Conference for Microsoft Technologies in Bulgaria

DevReach is the name of the conference for Microsoft Technologies, which will be held on 9 and 10 Oct 2006 in Sofia, Bulgaria.
The primary focus of the foreign and local lectors will be ASP.NET and SQL Server 2005. Check out the sessions and register for the event.

Sunday, August 06, 2006

Compact Framework 2.0 Service Pack 1 Pach

Compact Framework 2.0 Service Pack 1 Patch is available for download.
It includes everything you need to update the .NET Compact Framework 2.0 to the .NET Compact Framework 2.0 SP1(including VS2005 support).
For details check the .NET Compact Framework Team's blog
Download it from here

Sunday, July 30, 2006

Sandcastle CTP is out/NDoc is dead!

Microsoft released July 2006 CTP of their Documentation Compilers For Managed Class Libraries. It is much like the NDoc Open Source Project

Sandcastle produces accurate, MSDN style, comprehensive documentation by reflecting over the source assemblies and optionally integrating XML Documentation Comments.

Sandcastle has the following key features:
  • Works with or without authored comments

  • Supports Generics and .NET Framework 2.0

  • Sandcastle has 2 main components (MrefBuilder and Build Assembler)

  • MrefBuilder generates reflection xml file for Build Assembler

  • Build Assembler includes syntax generation, transformation..etc

  • Sandcastle is used internally to build .Net Framework documentation

  • Sandcastle should provide support for XAML as well.



Recently Kevin Downs (the leader of NDoc) sent a mail to the NDoc community saying that NDoc is dead!. That was a cool project that I've used many times and never gave a donation at all! We all should reconsider our community involvement!

Get more details about Sandcastle and NDoc's death here at the Scott Hanselman's blog and The Sandcastle blog

Pictures from MS Dev Days 2006 Bulgaria

Martin has few pictures from Microsoft Dev Days 2006, published on his blog.

Thursday, July 27, 2006

Atlas to be released in .NET Framework 3.5

A guy named Alian said in his blog that hopefully Atlas will be released till the end of the year and will be released as a part of .NET Framework 3.5 (codename "Orcas"). Does it mean that we will have . NET Framework 3.5 after few months?
Hey, I've just started loosing with all these .NET framework releases

LLBLGen 2.0 - Implementing Entity Factory Mapper

We've just finished upgrading our current project to LLBLGen v2.0. It provides a lot new features including some .NET 2.0. goodies. One of these new stunning features is the support for generic entity collections. Our project involves development of ASP.NET based application framework, which needs to construct and fetch entity collection run-time (Adapter scenario).

The common pattern for doing this with LLBLGen 2.0 in the Adapter scenario is like this:

EntityCollection<CustomerEntity> customers = new EntityCollection<CustomerEntity>(new CustomerEntityFactory());
DataAccessAdapter adapter = new DataAccessAdapter();
adapter.FetchEntityCollection(customers);



We've got a class called DataAccessManager, which is intended to be used like this:
EnityCollection<CustomerEntity> customers = DataAccessManager.FetchEntityCollection<CustomerEntity>(null);

...and the implementation(simplified version):

   public static class DataAccessManager
  {
      ..
         public static EntityCollection FetchEntityCollection(IPredicateExpression expression) where T : EntityBase2
         {
            EntityCollection collection = new EntityCollection();
            Type factoryType = EntityFactoryMapper.GetFactoryType(typeof(T));
            IEntityFactory2 factory = (IEntityFactory2)Activator.CreateInstance(factoryType);
            collection.EntityFactoryToUse = factory;
            DataAccessAdapter adapter = new DataAccessAdapter(connectionString);
            adapter.FetchEntityCollection(collection,expression);
            return collection;
         }
   }


The problem in the upper implementation is that we haven't found "out of the box" mechanism to map EntityBase2 type to IEntityFactory implementation. So we've managed to generate such a class by adding a new LLBLGen template.

We wanted to have our mappign pattern like this:
Type t = typeof(CustomerEntity);
IEntityFactory2 entityFactoryType = EntityFactoryMapper.GetFactoryType(t);


and the implemenation like this(not quite elegant solution):

   public class EntityFactoryMapper
   {
      public static Type GetFactoryType(Type entityType)
      {
         if(entityType == typeof(CustomerEntity))
            return typeof(CustomerEntityFactory);
         else
            if(entityType == typeof(OrderEntity))
               return typeof(OrderEntityFactory);
                  else
                  ....


In order to this we've created a new template file:
[DEVICE]:\Program Files\Solutions Design\LLBLGen Pro v2.0\Templates\SharedTemplates\Net2.x\C#\FactoryMapper.template

and we've added the following lines :
using System;
namespace <[RootNamespace]>
{

///


//Entity-Type To EntityFactory Type mapper
///

using YourProjectNamespace.EntityClasses;
using YourProjectNamespace.FactoryClasses;

   public class EntityFactoryMapper
   {
      public static Type GetFactoryType(Type entityType)
      {
         <[Foreach Entity CrLf]>
         if(entityType == typeof(<[CurrentEntityName]>Entity))
            return typeof(<[CurrentEntityName]>EntityFactory);
         else
            <[NextForeach]>
               return null;
      }
   }
}

After generating the code again we've received our new class EntityFactoryMapper ready for usage

Monday, July 24, 2006

Microsoft published Device Emulator source

The V1 Device Emulator source code is released by Microsoft under a shared-source initiative.
You can compile the emulator yourself, using Visual Studio 2005, and either run it as a standalone Windows application, or use its COM self-registration code to make it the default DeviceEmulator on your PC (meaning launch it and use it from Visual Studio 2005 and the Device Emulator Manager). The Shared Source release does not include sources to the Device Emulator Manager application or to the ActiveSync-over-DMA code, both of which are present in binary form in the V1 release.


Download link

Wednesday, July 05, 2006

Windows Mobile Tweaks

Following a list of registry based tweaks for Windows Mobile
USE IT ON YOUR OWN RISK!
Disable menu animations
To disable menu animations (sliding in&out) and speed up
performance of the UI a bit:

HKLM|SYSTEM|GWE|Menu|AniType = 0


To change it back to the default:

HKLM|SYSTEM|GWE|Menu|AniType = 6




Disable window animations
To disable window animations (minimizing/maximizing)
and speed up performance of the UI a bit:

HKLM|SYSTEM|GWE|Animate = 0


And to switch them back on:

HKLM|SYSTEM|GWE|Animate = 1




Add a 'Disconnect' button (and Timer) to the
Connection List for GPRS

To add a Disconnect button:

HKLM|ControlPanel|Phone|Flags2 = 8


To add a Disconnect button and a timer display showing
how long GRPS is in use for the session:

HKLM|ControlPanel|Phone|Flags2 = 16


To disable both the Disconnect button and the timer :

HKLM|ControlPanel|Phone|Flags2 = 0




Default SMS Delivery Notifications to on
To always have SMS Delivery Notifications enabled:

HKCU|Software|Microsoft|Inbox|Settings|SMSDeliveryNotify = 1


To disable them (can still enable per-SMS in SMS settings):

HKCU|Software|Microsoft|Inbox|Settings|SMSDeliveryNotify = 0



Note that SMS Delivery Notifications
are a network provider option,
and the recipient may refuse them to be sent out


Make reminders show only once
By default, reminders will keep bugging you for 2 minutes.
You can change this to zero minutes by adjusting this value:

HKCU|ControlPanel|Notifications|Reminders|AutoSnooze|AutoSnoozeMins = 0



Note that you can set this to any value you like.
Alternative to setting this value to zero is to delete the
'AutoSnooze' key altogether


Disable the SMS Sent notification
If you're tired of the "Message Sent" notification after sending
an SMS text message, you can disable them:

HKLM|Software|Microsoft|Inbox|Settings|SMSNoSentMsg = 1


And to re-enable:

HKLM|Software|Microsoft|Inbox|Settings|SMSNoSentMsg = 0


Please note that the 'Settings'
key may not exist in your device, and thus may have to be created first.


Change the SMS Sent notification text
If you just want the "Message Sent" notification to read
something different, adjust the following:

HKLM|Software|Microsoft|Inbox|Svc|SMS|MessageSent = "Message Sent"




See the full list here

Tuesday, July 04, 2006

Eric Rudder in Sofia

I just came from 2 meetings held today in the local Microsoft office. The purpose of the meetings was Eric Rudder(Microsoft Senior Vice President for the Developer Platform Evangelism Division) to meet with the local ISVs( in the first meeting)and with the local .NET User Group members(in the later one).
The atmosphere was informal and it was more like Q&A session. The second session (with the .NET User Group members) was more technical and it was really cool. I really enjoyed it! We had a little after party with a lot of technical P2P discussions.
The Q&As was mostly about the WCF. There was also a Bulgarian guy(George Kremenliev) from the WCF testing team, who gave us some additional interesting bits. I hope he will be able to make a session in front of the .NET User Group, soon.
Eric talked about the future of the MS technologies and answered tons of technical questions about the various TREE LETTER ACRONYMS and I think most of the guys there were excited to meet him.

Shortcuts – My Windows Vista Sidebar Gadget

I read a tutorial about building Windows Vista Sidebar Gadget and decided to try it myself. So this will be my first (and hopefully not the last) Windows Vista Sidebar Gadget – a gadget to display some usefull shortcuts.

The first problem I faced is the need to have a better knowledge on javascript. Fortunately, lately I ‘m working on a projects based on Atlas , so I ‘ve learned some basic javascript stuff. It would be even better if the Sidebar API was based on the Atlas client-side API – this is where I’ve invested a couple months digging into…Anyway, the second problem for me is the visual appearance of my gadget – I can’t do the design stuff, but anyway I’ve made some quick images with Paint.So here are the features in short:

  • display a list of clickable shortcuts
  • clicking over a shortcut, triggers execution of some shell command
  • support for adding new shortcuts.
  • support for deleting shortcuts

In general writing a gadget is similar to writing a web site with client-side scripting only – it contains HTML , CSS, JS, media, etc. So that’s how it looks like in the gadgets gallery:



After installing the gadget , it displays some default shortcuts

Only the last shortcut may be deleted – that is not quite user friendly , but it was easier for me :-)



Clicking on settings of the gadget provides dialog to add a new shortcut. The user may clear all shortcuts as well.



The gadget code may be downloaded from here. It is not completed in anyway and has some bugs as well. The zip file contains installation instructions.

There is a lot of room for improvements… but no time at all

Monday, July 03, 2006

The real value of the SecureString

I found recently an interesting blog dedicated mostly to security issues authored by a Security Development MVP named Valery.

Among the other intriguing posts, I found this post discussing the real value of the SecureString class

Sunday, July 02, 2006

SQL Server 2005 Everywhere CTP is available

The Sql Server 2005 Everywhere Edition CTP is available for download
Microsoft SQL Server 2005 Everywhere Edition offers essential relational database functionality in a compact footprint ideal for embedding in mobile and desktop applications including a new generation of occasionally connected dynamic applications.
Read more here
Download link

Unable to install Visual Stidio 2005 on Windows Vista Beta 2

I just tried to install VS2005 on my Vista Beta 2 box and received an error message saying that the setup process was terminated.

Few minutes googling and the solution was there: I just had to install msxml6 before proceeding with the VS2005 installation. And that may be done by launching the msxml6 installer from:

[DVD]\wcu\MSXML\msxml6.msi

Then I launched VS2005 installer again and everything was just fine.


Friday, June 30, 2006

Explosion in Sofia

I found this picture showing Sofia on 1.Jan.2005 at 00:00h.
I didn't know they sell this stuff to everybody :-)

Monday, June 26, 2006

Microsoft Robotics Studio CTP 1

Microsoft presented Microsoft Robotics Studio CTP 1 at RoboBusiness Conference and Exposition 2006. It is intended to provide common development platform for robotic development. Find more details and download link here

I’ve just installed it and discovered that the CTP contains a sample service implementation for RCX20. I hope I will able to write some interesting stuff for my RCX with VS2005 and the Robotic Studio

Stay tuned for more on this topic


 

…Still publishing with Word 2007 Beta

BLinq

Check out this tool called BLinq (Web Linq). It generates ASP.NET web sites from a database schema. It uses the May LINQ Community Tech Preview.

Download the prototype and read more here

I'm very excited from the new MS Word 2007 Publish/Blog feature. It is really cool!

The .NET Framework 3.0 Pre-Release

The .NET Framework 3.0 Pre-Release is available for download. Download it hereThe .NET Framework 3.0 is the new name for the set of technologies previously known as WinFX. However it is run on top of the .NET Framework 2.0 CLR. It will be available for Windows XP , Windows Server 2003 and Vista.Get more details here and here

.NET Compact Framework 2.0 SP1 is out

.NET Compact Framework 2.0 Service Pack 1 is in the process of being released.
Check the .NET Compact Framework Team blog for details.
It may be downloaded here

Thursday, June 22, 2006

AJAX on Mobile Devices

This post on channel9 , talks about using AJAX in Pocket IE

Tuesday, June 20, 2006

Phone calls in the Device Emulator

Have you ever wanted to test your phone enabled application without actually using real phone calls?
Windows Mobile 5.0 Phone Edition image for the Device Emulator allows this. It contains a virtual radio driver (fakeril), which allows testing such a functionality by using special dial numbers.
The following numbers may be used for test purposes:




SMS look back number: 1-425-001-0001

Voice numbers:

7272470,7272620,7272688
7272979,7272917,7272263
7274390,7274388,7274386,7274389

Data numbers:

7272455, 7272931, 727343, 7273432

Always busy:

7272024

Never answer:

7272773

Emergency:

911, 112, 08, 999

SMS:

0010001, 0010002

Monday, June 19, 2006

Error 2755 and MSI

I was surprised getting strange error, while trying to run an MSI produced with VS2005
The error was saying:

.The system cannot open the device specified. The installer has encountered an unexpected error installing this package.This may indicate a problem with this package.The error code is 2755.

Finally, Google says that this error is encountered when the install image is placed on an encrypted volume. After moving the installer to non encrypted volume , the error disappear

Sunday, June 18, 2006

Interprocess Communication with the .NET Compact Framework 1.0

To implement IPC in a .NET Compact Framework 1.0 application, a number of options are available:

  • Named events

  • Windows messages

  • Point-to-point message queues

  • TCP sockets

  • Memory mapped files

  • Registry

  • File system

  • Database



See the original article.

Thursday, June 15, 2006

MS Days 2006

MS Days 2006 will be held on 21st and 22nd June at Arena Cinema, Mladost (Sofia)
Those who want to attend may register here.

I will present a session about .NET Compact Framwork Development together with Tihomir Ignatov.
I will also participate in the second session held by Intelligent Systems Bulgaria to present our mobile solution for Microsoft Dynamics NAV


Wednesday, June 14, 2006

Radio tangra is back!

One of my favourite radio stations is back!
http://www.radiotangra.com/

Sunday, June 11, 2006

Are we going to write device drivers in unmanaged code?

Writing device drivers in managed code this days is not possible. However, I found this interesting article from Chris Tacke comparing the performance of managed vs unmanaged code.

Friday, June 09, 2006

Mobile Client Software Factory – CTP Release

The CTP release of the Mobile Client Software Factory is out.
The Mobile Client Software Factory provides an integrated set of guidance to help architects and developers create line-of-business Windows Mobile applications that interact with back-end systems over various networks (WiFi, GPRS, etc.) that might be intermittently available. A mobile smart client line-of-business application has one or more of the following characteristics:

* It has a rich user interface that takes advantage of the power of the Windows Mobile device.
* It connects to and exchanges data with multiple back-end systems through a gateway server through the most cost effective underlying network technology.
* It takes advantage of local caching and processing to enable operation during periods of no network connectivity or intermittent network connectivity.
* It is easily deployed and configured.
* It keeps local, potentially confidential information secure.


In short the Mobile Client Software Factory contains the following goodies :

  • Composite UI Application Block ported into the .NET Compact Framework
  • Application blocks
  • Guidance Automation Toolkit
  • Quick Starts Examples
  • Reference Implementation

Unspecified error 80004005

Lately, I am working over a Visual Studio 2005 Add-In for our NavMobile product. It is meant to allow our partners to be more productive, while customizing the solution for their customers. Yesterday, we've spent some time clearing old stuff from our central source repository.
Later, I've opened the Add-In Project and this message box appeared on my desktop after running the project:

This message was not quite helpful for me, although I knew there is a problem with the output assembly loading. I've tried some goggling, but no luck. I've checked the \BIN folder security settings, but there wasn't anything wrong. Finally, after an hour or so I solved my problem.

When a new project of type "Extensibility/Visual Studio Add-in" is created you'll get a bunch of files, including 2 files with ".Add-In " extension.
1.MyAddInProject.AddIn
2.MyAddInProject - For Testing.AddIn".

However during our source repository clearing, we've accidentally deleted the file #2. This file is created by default in ...\My Documents\Visual Studio 2005\AddIns
When I've opened the project first I saw the file #2 is missing. I've created a file with the same name and copied the content from file #1. And this was the reason to get the error message.

These files contain XML describing the Add-In and they are used by VS2005 in order to know which Add-Ins to load. The files contain a tag named /Extensibility/Addin/Assembly,which points to the Add-In assembly name. However, by default file #2 contains the full path to the assembly Add-Ins and file #1 contains only the name of the assembly.

The error dissappeared after placing the full path to the assembly Add-In in the /Extensibility/Addin/Assembly tag.

In general: if you get such an error, while trying to debug your Add-In, check if the assembly path written in file #2 is "visible" for VS2005.

Wednesday, May 17, 2006

Will WPF/E replace CF?

I read this interesting article discussing the new Microsoft initiative based on Windows Presentation Foundation called Windows Presentation Foundation Everywhere (WPF/E). The author gives some early bits about the initiative:

  • Will provide subset of the XAML and CLR functionality
  • Supported on platforms other than Windows
  • Available as a internet browser plugin
  • No need to have .NET installed
  • Download size under 2 MB
  • Available in the first half of 2007


See the full article here

Thursday, May 11, 2006

Performance problems on WM5.0

Are you experience performance problems on your WM 5.0 device
This post at Windows Mobile Team's blog explains some issues related to the WM 5.0 Compaction thread

Monday, April 24, 2006

NET Compact Framework 2.0 SP1 Beta is out

.NET Compact Framework 2.0 SP1 Beta is now available! See more details at the Compact Framework Team's blog.
There are number of new features and a lot of bug fixes. The long waited WinCe 4.2 support is already a fact! Another great new feature is the
.Net Compact Framework Remote Performance Monitor. It may be downloaded here

Thursday, April 06, 2006

How to drop all tables from a database(MSSQL)

I had a problem upgrading one of may dotnetnuke based portals and I needed to start over with a fresh database. Due to some hosting issues I couldn't drop and recreate the database. I had a large number of objects and needed a quick magic sentence to drop them all. fortunately the following ones did the job:

I deleted all table with:
exec sp_MSforeachtable "DROP TABLE ? PRINT '? dropped' "

And then used the following statements to drop procedures
create procedure DropSPViews
as

-- variable to object name
declare @name varchar(100)
-- variable to hold object type
declare @xtype char(1)
-- variable to hold sql string
declare @sqlstring nvarchar(1000)

declare SPViews_cursor cursor for
SELECT sysobjects.name, sysobjects.xtype
FROM sysobjects
join sysusers on sysobjects.uid = sysusers.uid
where OBJECTPROPERTY(sysobjects.id, N'IsProcedure') = 1
or OBJECTPROPERTY(sysobjects.id, N'IsView') = 1 and sysusers.name =
'USERNAME'

open SPViews_cursor

fetch next from SPViews_cursor into @name, @xtype

while @@fetch_status = 0
begin
-- test object type if it is a stored procedure
if @xtype = 'P'
begin
set @sqlstring = 'drop procedure ' + @name
exec sp_executesql @sqlstring
set @sqlstring = ' '
end
-- test object type if it is a view
if @xtype = 'V'
begin
set @sqlstring = 'drop view ' + @name
exec sp_executesql @sqlstring
set @sqlstring = ' '
end

-- get next record
fetch next from SPViews_cursor into @name, @xtype
end

close SPViews_cursor
deallocate SPViews_cursor


this is the original source

Friday, March 31, 2006

How about your .NET tools list?

My dev.team is just about to start Sprint 1 for our new project. It targets .NET 2.0, ASP.NET 2.0 , MSMQ, MSSQL2005,...
We did a good preparation and finally we're ready to roll out. Along with the sprint backlog preparation, we've picked up our dev. tools/libs as follows:


Dev.Environment:Visual Studio 2005 Professional Edition
Continues Integration: CruiseControl.NET
Unit Testing:NUnit
Conformance analysisFxCop
Build ToolMSBuild
Tracking System: Axosoft OnTime 2006
ORM/Code Generation: LLBLGen Pro

We've also picked up MS Enterprise Library 2.0 in order to have more scalable monitoring and instrumentation schema.






Tuesday, February 21, 2006

Web Services,Datasets and Compact Framework

Transferring datasets through the wire between a Compact Framework based application and Web Service is a common data transfer practice. However, it may turns to a big pain from a performance point of view if not done properly.

So, when dealing with datasets consider the following approaches:


  • Design your application so that only the needed data is transferred. For example transfer only changed data. In case you are targeting CF2.0 you may use DataSet.GetChanges() and DataSet.Merge() methods. However if you are still targeting CF1.0 you should deal with it manually. This post explains it in general


  • Compress the data transferred. Read the following articles:



  • And finally serialize DataSet to Xml and then send it over the wire as a string. This could improve performance in some scenarios; prototype, measure and analyze to see if this could really help in your particular case. Transfer the DataSet schema as well to imrpove DataSet load time

Wednesday, February 08, 2006

Data transfer options between mobile devices and Desktop with Compact Framework

Following brief list of data transfer options, which may be used in CF applications:

1.Sockets
   The following classes from System.Net.Sockets namespace may be used for TCP/IP based communication: Socket,TcpClient and TcpListener. They provide a fast stream-based communication model.
This post of David Kline provide a simple object remoting by using Xml serialization and TcpClient/TcpListener

2.HTTP Request
   Namespace System.Net provide 2 classes (HttpWebRequest,HttpWebResponse) which may be use to deal with raw http requests.
See more here and here

3.Xml Web Services
   .NET CF provide good support for Xm Web Services consuming. According to MSDN it is the "primary feature" of the compact framework. Consuming Xml Web Service is easier as pointing the location of the web service.
A good start may be found here

4.Sql Ce and Remote Data Access (RDA)
   RDA is a lightweight mechanism for data synchronization between Sql Server Mobile(Sql Ce) and Sql Server running on the PC. You may store your data locally on the mobile side in Sql Ce database and synchronize the data with a remote Sql Server database when the device is connected.
See more here and here

5.Sql Ce Merge Replication
   It is just another and more powerful approach for synchronizing data between Sql Ce and Sql Server databases. Sql Ce Merge replication is based on SQL Server merge replication. It requires more configuration and maintenance at the server, but provides built-in and custom conflict resolution capabilities and tools for configuration and monitoring
See more here

6.RAPI
RAPI stands for "Remote API". It allows desktop applications to make function calls on the mobile device.
See more here
OpenNETCF Desktop Communication namespace provide easier way to make your desktop application RAPI enabled

7.ActiveSync data synchronization
ActiveSync may be used for automatic synchronization of contacts,calendar and even files. You need to just to put the files in the right folder.
See more here

8.File copying over a network share
Files may be copied by using windows network shares.

Selecting the right way to transfer data requires good understanding of the pros and cons. A lot of factors should be considered before taking the right one. Some of these factors are maintenance, scalability, locus-control, performance, dev.cost, interoperability,security,the mobile platform characteristics,etc.

Thursday, January 26, 2006

Portable Database Choice

This is a really nice post discussing portale database choise related issues

Migrating to SqLite - Part 2

What took us to migrate to SqLite?


In general we had the following checklist:
1.Replace the classes from the System.Data.SqlCe namespace with the classes from the System.Data.SqLite namespace.
2. DataType compatibility problems
3. Foreign key related problems
4. Sql syntax compatibility problems


The migration became really easy and smooth. The major reason was the system architecture. Our system design utilizes the common idea for separating the business and data access logic. Out business logic layer operates over custom business objects (not DataSets) and invokes the data access layer for fetching and persistence operations. It has a performance impact of course, however it is a reasonable tradeoff I may say.

Checklist item #1:
We have only one place in our code to create IDataConnection implementations:
The code is like:
public IDataConnection GetConnection()
{
return new System.Data.SqlServerCe.SqlCeConnection(cnnString)
}

so we've changed it to
public IDataConnection GetConnection()
{
return System.Data.SQLite.SQLiteConnection(cnnString)
}

We use IDataCommand, IDataParameter,IDataReader and other interfaces to perform the actual database interactions. So we didn't change anything in data manipulating routines. The code was like:
using(IDataConnection cnn=DataManager.GetConnection())
{
cnn.Open()
IDataCommand cmd = cnn.GetCommand(cnn);
cmd.CommandText = "Select * from sometable";
...
IDataReader reader = cmd.ExecuteDataReader()
...


Checklist item #2
Are we going to have issues related to data types. For example very often the datetime data type may be a big pain when using the same code to access different dbms. So we did a test application where we performed some database operations identified as potentially problematic. The operations involved reading, selecting, fitlering ,joining and aggregating in SqLite db populated with a real data (from a customer). We have operations with DataReaders,ExecuteScalar calls,etc. It showed us the problematic areas and they were few indeed.

Checklist item #3
Fortunately it was not a big deal for us. Our data access layer provide some features usually available in the ORM products and dealing with business objects relations at application and database levels was one of them.

Checklist item #4
The test application helped us to identify the possible problems. In general there was no need to rewrite sql statements. We had the following issues:
- statements for the foreign constraint creation
- primary key creation statements. We used ALTER TABLE ..ADD PRIMARY KEY, which is not supported in SqLite

Note that this post only scratches the surface of the possible problems around such a migration.The issues are of course specific to the actual application migrted.
What was the benefit?
The migration process helped us to identify some design and implementation issues in our code so in result we had a better code as a whole. And we have a really better performing application as a whole. The bottleneck features are performing up to 9 times faster after migration. It worth it!

Migrating from SqlMobile 2005 to SqLite requires understanding of the tradeoffs which have to be made.
Read the SqLite documentation and make a test bed before before proceeding.

Migrating to SqLite -Part 1

Finally I am taking my time to blog

We decided to investigate the idea for migrating our product from Sql Mobile 2005 to SqLite in order to benefit from the better performance. This was decided after investigating a large list of performance optimization tips without having the desired results.

We have 2 features identified as unacceptable from a performance point of view:
The first one involves a "discounts and prices calculation", which involves a number of unrelated db hits (no way to rewrite them as one). There are some scenarios, when this takes too long time to have the user satisfied. The second is the synchronization feature of the product. It has the ability to synchronize the mobile database with a remote (server-side )system using our proprietary mechanism. It is actually the most important feature from a marketing point of view. It involves massive insert and update operations. In most cases sync operation takes few seconds, however there are some scenarios, when the customer has a really huge amount of data and initial bulk loading of the mobile system may take few minutes. And we don't want to have the user waiting so long.

Some of the considerations against that migration was :
- the lack of database level encryption
- the lack of foreign key constraints enforcement
- the lack of strong type enforcement at a database level.
- the lack of experience with SqLite

However spending some time with SqLite in combination with the last version of the ADO .NET 2.0 SqLite Data Provider
made us optimistic about the success.

What it took us to migrate to SqLite? See here.