Sunday, October 25, 2009

The Conditional Attribute

 

The conditional attribute is a really cool why of compiling in or out an entire method in your code. The cool thing about it is the compiler automatically compiles in/out not only the method itself, but also all the calls to it.

The conditional attribute works with conditional compilation variables, which can be set in the Project Properties window on the Build tab. By default the Debug build defines a DEBUG variable, which is often useful.

ConditionalCompilationConstants

Once you’ve got a variable defined for your purpose, you decorate your method with the conditional attribute and provide the variable name. Let’s say you have a LogDebugInfo method that you only want called in debug builds. Declare the method like this;

[Conditional("DEBUG")]
private void LogDebugInfo(string debugInfo)
{
  //Code here to log the value of debugInfo.
}


Now all you have to do is call the method as you normally would. When you compile or run your code as a debug build the LogDebugInfo method will be called normally, but when you build a release version the LogDebugInfo method and all calls to it will be stripped out of your code automatically.



You need to be careful though, that your methods that are marked with the Conditional attribute have no side-effects on the state of your application. That is, they should not change class level fields or static values, or create or dispose objects that the rest of your code depends on. If you’re not careful about that, you may end up with errors that occur in one build and not another because some part of your code is dependent of state that only occurs when the conditional method is compiled in.



Having said all that, and while I believe the Conditional Attribute is cool where you can use it, there are some subtle gotcha’s that Eric Lippert has explained on his blog.






Tuesday, October 20, 2009

Coding Light: On Teachability in Team Development

Another great post from David Morton;

Coding Light: On Teachability in Team Development

I've certainly met a few of each of these types of developers (especially the arrogant ones, whos code usually ends up being re-written after they've left).

Coding Light: Closures in C#

David Morton has a short but interesting post on his blog, about Linq and Closures in C#. Check it out;

Coding Light: Closures in C#

Sunday, October 18, 2009

Pos .Net Series, Post #12 – Sample Check (Cheque) Scanner Application

This is the twelfth post in a series on Pos .Net. You can find the first post here, or see all the posts here. You can get the sample code for this post here.

I have created a sample application for integrating to a Pos .Net CheckScanner device. While this code is only a sample, I think it will be useful as the CheckScanner is one of the more complex Pos .Net devices and has a relatively ugly programmatic interface.

If you are going to integrate to a CheckScanner device in your application you must read the section of the Pos .Net SDK help that begins

“The basic programming model for the CheckScanner interface is as follows:”

Without reading that, you are likely to make mistakes. For example, the interface for the device has a RetrieveImage method and an ImageData property. It would make sense that calling RetrieveImage would fill the ImageData property (although a return value from the method would have been better)… and it does, but not synchronously.

This means if you immediately follow your call RetrieveImage with a call to the get accessor of the ImageData property you will likely get only a partial image, no data, or an error. One poster in the Pos .Net forum had exactly this problem.

There are other issues too, such as when to call RetrieveImage, and how to write your code so it works with devices that require an explicit BeginInsertion/EndInsertion/BeginRemoval/EndRemoval and those that don’t (always use those methods, you can’t tell if the device needs them or not, and they should be harmless when called on a device that doesn’t need them). There can also be issued with error handling around the insert and remove methods, and which state the device is left in in the event of an error… again the ‘programming model’ section of the CheckScanner class documentation talks about these issues.

The sample I’ve posted is very simple, it doesn’t deal with storing images in the device or with performing validation/MICR reads at the same time as the scan but it will demonstrate how to simply capture the image of the scanned document without any major issues.

If you find this sample helpful, please leave a comment.


Monday, October 12, 2009

Sunday, October 11, 2009

Pos .Net Series, Post #11 – Sharing Devices Across A Network

This is the eleventh post in a series on Pos .Net. You can find the first post here, or see all the posts here. You can get the sample code for this post here.

Pos .Net doesn’t natively support sharing devices across a network. The only networking feature available in Pos .Net is the ability to use a device connected to the local machine when the software is being run under a terminal sessions via Microsoft Terminal Server. While this is useful in some situations, many people want to be able to share a device attached to one machine so it can be used from others, in much the same way as Windows allows sharing of printers.

While Pos .Net doesn’t provide this feature itself, you can implement your own device sharing architecture. Doing this properly is not for the faint hearted though. I’ve posted some sample code for sharing a PosPrinter object between multiple PC’s here. The sample uses .Net Remoting to handle the network requests, you may prefer to use a more modern technology such WCF, but I used remoting in the sample because it was one of the simplest mechanisms available and required less code to make it work.

The sample I’ve provided is obviously not intended for production use. It only demonstrates sharing a a PosPrinter, and not any other types of device. Sharing other ‘output’ devices could be done easily by extending the code, but input devices (such as Barcode Scanners and MSRs) would require significantly more work as the server must also become a client, and the client also a server to enable the two-way communication required. The architecture for an input device would be very similar to the WS-POS specification which uses web services to share devices across the network.The sample code also doesn’t contain any error handling and so isn’t robust enough for a real world implementation. Finally, the sample also supports only a limited set of printing functionality. To fully implement a shared printer you would need to build your own PML to allow single-call printing of entire documents with a full feature set. Trying to implement the device any other way will likely result in a system that is too slow and not robust enough, as it will involve too many network calls.

The code in the sample is heavily commented, with some comments explaining the general architecture and others explaining what the code does. While comments that explain what code does are typically bad, since this is a sample designed to be used as a learning tool and everyone who views it will have a different level of knowledge, I felt it was appropriate to provide as many comments of both sorts as possible.

You will need to properly configure or disable firewalls on both the client and server, and ensure both machines can see each other on the network, in order for the sample to work correctly. This will be a problem with pretty much any networking implementation.

The sample code is split into four projects. First, there is a ‘common’ library which contains interfaces and base classes that are required on both the server and the client machines to enable the remote communication. There is a server library which contains a DeviceManager class, which an be instantiated in any host process that can act as a remoting server (i.e a windows service, windows application, ASP .Net application etc). This class is responsible for locating and opening the locally attached Pos .Net devices and setting up the code that listens for and processes incoming requests to use the devices. There is also a very simple Windows Forms application that loads the device manager, for the purposes of the demo. Finally there is a client application that communicates with the server, and allows the user to select a printer and then print simple text to it. Technically you can also print text containing escape codes using the sample if you can embed them in the sting sent to the remote server, but there is no support for printing barcodes, bitmaps and so on.

So, the server application depends on the server library and the common library. The client application depends only on the common library.

Some pieces of the architecture may seem a bit odd at first. For example, the DeviceManager class stores and exposes via a property a static collection of Pos .Net devices. The remote device classes which handle requests for specific device classes obtain a reference to a device from this static collection on every request, and then use that reference for their work. The static collection is used so the devices do not have to be located, instantiated and opened on every remote call, and this helps to improve the performance of the system. It would seem, however, to have been simpler to just have the remote device class to use a field to keep a reference to the particular Pos .Net device object it is associated with. Unfortunately this is not possible, for an object to be accessible it must be serialisable but the Pos .Net objects aren’t and so any class that has a field or public member that exposes a Pos .Net object cannot be serialised. Therefore, it is not possible to refer to a Pos .Net object inside the remote device classes except within the local scope of a method, and therefore the static collection on DeviceManager is used.

Another issue I had with the remoting was that some of the .Net enumeration types could not be exposed on public interfaces due to security issues (or so .Net claimed), therefore the printer station parameter on the print method of the remote pos printer class accepts an integer for the station and not the enum value. You can however cast the enum value to an int when passing it, so you can continue to use the enumeration values for convenience.

The way a client communicates with the server is relatively simple. First, the client obtains a list of available devices by name using the GetDeviceList method. In the sample, these names are loaded into a combobox where the user can select a device to work with. The client may then request a ‘remote device object’ using the GetDevice call and passing in the name of the device it wants to work with. The object retuned must then be cast to the interface of the remote device type being worked with, which in the case of the sample is always IRemotePosPrinter since only PosPrinters have been implemented. Once a remote device object reference has been obtained, the methods and properties of the interface can be called just like any other object, and these calls will be sent to the server via the .Net Remoting system and the actual code will then execute on the server side.

So, check out the sample and if you’re game feel free to base your own system on it’s design.


Technorati Tags: ,,,,

Wednesday, October 07, 2009

The Brads – a comic about web design

I love the second strip down (about the Digg bar).

The Brads – a comic about web design

Google Attempts to Explain What a Web Browser Is [VIDEO]

Regardless of what browsers started out being, I'd define any (popular) modern browser as a "generic thick client for running multiple on-line applications".

Yes, a browser is a thick/rich client, it's just not one that runs a single application. There, I said it.

Anyway, that's not quite what Google was trying to say, so here's the link to their content (which is more a defintion for a lay person, as well as a distinction between a browser and search engine etc);

Google Attempts to Explain What a Web Browser Is [VIDEO]

Tuesday, October 06, 2009

Sunday, October 04, 2009

Pos .Net Series, Post #10 - Signature Capture Devices

A couple of people on the Pos .Net forum have been struggling with signature capture devices, specifically where the captured signature is skewed when drawn from the point data returned by the device. It turns out there are several ways of converting the data from the devices into the point data returned by Pos .Net and not all devices use the same one. The Ingenico device apparently requires a specific setting, and others may do as well.

There is no way of setting this via the common Pos .Net interfaces, but luckily there is a solution which has been posted here by Sylvester (one of the Windows Embedded Team members).

Sylvester has also posted another useful (but distressing) tip for handling cancelling of the signature capture process.


Technorati Tags: ,,,

Friday, October 02, 2009

Yet Another Reason To Hate Floats

Ok, so I stole that line from Strilanc on the Microsoft Code Contract Forum  but he has a point. This is another one of those things that makes me want to stop writing code.

So, what’s the problem ? Well it would appear that comparing a parameter of type double with a field of type double won’t necessarily end up with matching values, even after the field has been set equal to the parameter. For the actual details of the problem see this;

False Warning: Possible precision mismatch for the arguments of ==

A better question would be why doesn’t the compiler generate a warning for this ? You can just imagine some poor developer somewhere scratching his head over why this doesn’t work, or worse, only doesn’t work in production… it hardly seems to be a well known or obvious issue.


Technorati Tags: ,,