Thursday 28 August 2008

.Net code comments: To use or not to use ?

There are different types of comments we "often" use in our code, for example, inline comments in methods, XML comments on classes, etc. Are these comments really useful ?

In my opinion, they are and will be useful if:

- they are precise and clear (no need to tell stories in your comments)
- they are updated together with the code they explicit (Revise your code comments)

XML comments enable Visual Studio to provide intellisense on your classes and methods. In addition to this, they can be used to generate techincal documents (e.g. .chm files with all your class and method descriptions).

Most of the time, inline comments won't be necessary provided that you have an intuitive method name with a precise XML comment. Depending on the complexity of the method, you'll be writing some inline comments explaining specific parts of your code. For example, we could do this to explain some complex business logic. Another solution could be to move this logic to another method having its own XML comments.

Once again, there is no one good solution to a problem. The best solution is the one which best suits the problem at hand.

I thank my colleagues for the discussion we had on the above subject.

Wednesday 21 May 2008

WCF CollectionDataContract and DataMember attributes

We often use the WCF CollectionDataContract on a data contract so that the latter is generated as a collection (and not as an array) in the WCF Service proxy.

One day, I tried to define a data member inside a CollectionDataContract. Strangely, the data member was not generated in my proxy. It seemed that was not possible with WCF 3.0 (http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=2413798&SiteID=1)

[CollectionDataContract(...)]
public class MyCollectionDataContract : List
{
...
[DataMember(..)]
public string MyDataMember
{
...
}
}

The MyDataMember was not generated in the MyCollectionDataContract in the proxy.

Tuesday 13 May 2008

Localizing error messages in client applications in SOA

Localizing error messages in a client application in a Service Oriented Architecture (SOA) might be a difficult task especially if you don't have control on the available services. Technical or functional errors might be returned in the form of text to client applications. Now, if these applications take these raw error messages and display them to their users, we'll have a strong dependency on the language used by the services and the client applications.

Services in an SOA do not need to worry about presentation logic. Instead, they are here to solve technical or business problems. It is the responsibility of client applications to translate results/errors returned by these services before presenting them to their users.

Let's take the example of a french application using a web service which returns its error messages in english. It would not be very appropriate to display english messages to french users. To solve this problem, we could have translations of all possible error messages on the client side, which we will display according to the error returned by the web service.

Here we have another problem. While doing error handling, we often test some conditions/exceptions to determine whether or not, we have an error. Testing for long text strings representing errors is a bad idea as we will have a strong dependency on the service error naming convention. If for example, on the service side, we change a word in the error message, there will be a mismatch on the client side, and consequently, we will not display the correct translated message in the client application.

One possible solution could be a scenario where the service returns error codes to its clients. Each of these error codes would indicate one type of error. Of course, both the client and the service, must agree on the semantics of these. Using this solution and in case of errors, client applications will first search the error message corresponding to the received error code from a resource file before displaying them to their users.

Wednesday 5 March 2008

Null object pattern

- Avoid using a null value to represent an error. An error is an error and it must be treated as such by throwing an exception.

- When returning a collection of objects, return an empty list if no results are obtained. The consumer method will not need to test if the returned collection is null or not. It will only need to verify that atleast one element is present in the collection to know that results were obtained.

- When returning results of a binary nature, initialize your binary variable to a default value. If you want to maintain 3 states (true, false, not set), use a class like the Nullable class of the .Net framework.

Remark: The use of any pattern depends on your problem context.

Thursday 31 January 2008

Excluding data contracts from a WCF service proxy class

It may happen that you do not want to generate your data contract classes in the proxy class of your service. For example, you might wish to deploy these data contracts in a separate assembly so as to share them between your different services.

To generate a WCF service proxy by excluding data contracts use the svcutil.exe command. You can execute this command in a visual studio command window.

Syntax: svcutil /et:<Fully qualified name of your data contract class> <Service URL>

Note that et: is the short form for excludeType. The above command is the same as:

svcutil /excludeType:<Fully qualified name of your data contract class> <Service URL>

The successful execution of the above command generates, in your current directory:
1. A proxy class
2. A configuration file for the proxy.

Tuesday 29 January 2008

Foreground versus background threads in .Net

At the end of a .Net application, all background threads are automatically aborted by the Common Language Runtime (CLR).

To set whether a thread is a background thread, use the IsBackground property of the Thread class.

While background threads end with your application, foreground threads continue to execute if not explicitly aborted/stopped. So it is up to you to ensure that all foreground threads of your application terminate/abort correctly.

Tuesday 22 January 2008

Visual Studio 2005 add-ins

Visual Studio provides many features such as Intellisense and keyboard/toolbar shorcuts which allow the developer to save time while coding his projects. If you want to develop even faster, you can install some useful addins:

GhostDoc:
A free tool which generates quite relevant XML comments for your methods with simple names. For methods with more complex names (which we should avoid !), you will need to review the comments as Ghostdoc currently does not utilise Artificial Intelligence for its deductions. But, I am sure that this idea will one day be incorporated in future code editors.

Property Manager:
With the refactoring feature of Visual studio 2005, you can generate only one property a time for the private fields of your class. The Property Manager is a free addin which can generate properties for multiple fields at a time.

The trick is simple:
- select the fields for which you want to generate properties,
- right-click and choose create property in the contextual menu,
- perform a paste operation (Ctrl + v) in your code to paste the property definitions.

Cool commands:
This addin provides some "cool" shorcuts in the contextual menus of your visual studio. Some examples are:
- compile a project from the code editor
- open the containing folder of your project from the solution explorer.
- flip open or flip close the projects list in the solution explorer.

JetBrains Resharper:
Resharper provides a suite of addins which greatly enhances your programming experience using Visual Studio 2005. The most interesting features are:
- real-time code analysis and recommendations for code optimization
- visual styles for the code editor
- more programmer friendly refactoring facilities.

Note, you must have a licence in order to use this tool. You can try the tool by downloading an evaluation version.

Monday 21 January 2008

Dirty programming versus clean programming

In my short development experience, I met developers who code like "pigs", that is, they violate all coding best practices (no matter they have time or not!). Most of the time, their argument to explain this, is that the time allocated for the task is too "short".

In all projects, we have time constraints. Does that mean, we should try to deliver things even if the work done behind is of a poor quality ? What is the degree of compromise between quality and delivery date ?

I personally think that in these cases, we should develop the most important modules of the project and inside these modules, we should deliver the most important functionalities, keeping in mind the quality requirements of the project.

For less important (less priority) functionalities, we should atleast try to put in place the code structure, that in future, will allow us to quicky and cleanly add the remaining functionalities.

In this process, we could use the Open-Closed principle, which says that a delivered software must not be modifiable but extensible: lets explain this. If you modify a delivered software, there is a risk of regression and side effects, for example, we could break existing functions of our software. But if our software is extensible, we can enrich it with new functionalities without touching to the existing ones.

Why I wrote this blog ?

Firstly, to share my short but valuable .Net experience.

Secondly, I hope that this blog will be visted by more experienced developers and architects who will validate its content.

The contents found on this blog are my ideas and my way of thinking. If you find content which is inconsistent, please do not hesitate to leave your comments which will permit me to bring the necessary corrections.

Friday 18 January 2008

Transactions in .Net

3 types of transactions:

ADO.Net Transaction (System.Data)
Limited to one database connection.


Enterprise services transactions. (System.ComponentModel)
- Uses the 2 phase commit protocol
- Needs a distributed transaction manager.

Transaction (System.Transactions)
Transactions taking advantage of the above two. It can determine whether or not to use a distributed transaction. For example, it uses a lightweight transaction in case of a single database connection or an operation which needs to be performed in the same network domain.

Use a transaction scope to "scope" a method/operation.
- required: If the operation has a TransactionScope.Required attribute, it joins the existing transaction scope or creates a new one if it does not exist.
- RequiresNew: Creates a transaction for each operation.
- Suppress: The operation will never be part of a transaction.

Transaction Isolation level:
- READ COMMITTED: we can only read committed data..
- SERIALIZABLE: Prevents other users from inserting/updating data until the transaction is complete. Most restrictive level.
- REPEATABLE READ : Shared locks are used for reading data. No dirty reads.
- READ UNCOMMITTED: No shared locks while reading data. Possible dirty reads.

Winforms - Anchor and Dock properties

I met several difficulties while trying to set the anchor and dock properties of Winform container controls such as panels and group boxes. That's why I give here, a brief explanation of these properties.

Anchor
This property controls the distance between a Winform control (button, combobox, panel) and its container control (panel, group box, etc).

At runtime, when you resize your form, the distance between your control and the edges of its container control (to which it is anchored) remains proportional to the distance "drawn" between them in design mode.

By default, this option is set to "Top, Left". Other possible options are "Right" and "Bottom".

Dock
This option allows you to attach a control such as a panel to one of the edges of your form. Possible options for this property are:

Top:
The control will always be displayed and attached to the top edge of your window.

Left:
The control will always be displayed and attached to the left edge of your window.

Right:
The control will always be displayed and attached to the right edge of your window.

Bottom:
The control will always be displayed and attached to the bottom edge of your window.

Fill:
The control will stretch to fill its container or form.

Note that in the case where more than one control have the same dock property in the same container/form, the first drawn control will have priority. For example, if you draw 2 panels in your form and set their dock properties to bottom. The first drawn panel will be displayed as the bottommost panel while second will be displayed just on top of the first one.

CAB Quick description

Composite Application UI Block (CAB)
CAB is a methodology for building user interface applications composed of modular blocks.

Modules
The working application is organized in terms of modules which can be plugged or unplugged without affecting the whole application. But, unplugging a module implies the disactivation of certain functionalities of the application. Modules communicate between them in a loosely coupled manner by using an event broker system.

Workitems
Each module contains one or more workitems. A workitem can be analogous to a Use Case (UML) and is a logical area (in memory) of the application, where we store items useful for one use case and eventually its sub use cases. WorkItems can contain sub workitems and elements such as Views (User controls), Services (instance of classes exposing methods to the whole workitem) and State variables. In fact, the workitem is a container where we "dump" things we need for executing a particular use case. It is to be noted that Views placed in a workitem are not directly displayed on screen. For this purpose we need CAB workspaces. Moreover, the parent of all workitems in a CAB application is the RootWorkItem. This workitem is created automatically.

Shell.
The shell is the starting project of your application and has the role of initializing the environment necessary for the execution of your application.

WorkItem state.
State variables are like web session variables where we store values in a key-value style. These values are then accessed or removed from the workitem by using the appropriate state key.

Services.
Services are classes instantiated and stored in a workitem. These methods are then accessible anywhere in the workitem and its subworkitems.

Workspaces.
Workspaces are placeholders on screen where we will display our user controls (Views). CAB proposes several types of workspaces such as MDI and tabbed workspaces. The MDI workspace, for instance, is used to display our user controls as child windows into our parent application.

CAB Event broker.
Communication between CAB modules is ensured by the CAB event broker. A module which needs to trigger an action in another module "publishes" (event publication) a message to the event broker which invokes all modules which have subscribed (event subscription) to the event.

Guidance Explorer

The Guidance Explorer is a tool developed by the Microsoft Patterns and Practices group. With this utility, the developer or architect has quick access to a series of best practices to a series of day-to-day development and archirectural problems: patterns proposed range from basic .Net issues to more advanced topics such performance and security.

The Guidance Explorer also integrates Q&A and code examples. You can download it from here.
Thanks to the P&P Community for their marvelous work.