Wednesday, June 29, 2005

System.Collections.SortedList performance

"Everything changed, when you are add scale."
One of thing which changed is performance requirements. I saw a set of classes in System.Collections and System.Collections.Specialised namespaces and really never thinked about differences between them.
It was trivial that ListDictionary faster SortedList or HashTable on small amount of data (<10), but actually I never used HashTable and didn't think about what it is.
Today i wrote simple Aspect Oriented Idea test and when playing with performance I accidentally found that HasDictionary is twice faster (for my case) than normal SortedList. (Key was Guid)
Such small changes - to compare hashCodes instead of key values could significantly increase performance of your system if it makes a lot of search operations.
Result: use SortedList only when you need really ordered values.
Applies to all dotnet languages: C#, VB.NET, C++.NET, J#

Thursday, June 23, 2005

Design Patterns Training Materials [Ru.Trainings]

Порылся и нашёл материалы, которые готовил для тренингов по паттернам проектирования где-то год назад - можете просто воспользоваться, а можете приглашать :)

Если кто знает что это такое и прочитал книгу Эрика Гаммы, то ничего особенного в этих материалах не найдёте. Однако если захотели кому-то попытаться объяснить что это такое за 45 минут, то может и пригодится.

http://dotnet.osypchuk.com/Sources/DesignPatternsTraining2004.zip

Word + Visio Diagrams,
Sorry, These materials was created in 2004 and in Russain language.

Calendar popup control

Cool and easy to use calendar control was created by Excentric World. And this component is free :)

It is fast because it uses DHTML to build Calendar, and do not require to open new prowser window. Only one problem with such kind of controls - it uses to much styles -selected day style, today style, holiday style, weekend style, etc.

http://www.eworldui.net/CustomControls/CalendarPopup.aspx

-- updated: However, Author closed this project and we cannot download this component now.

Wednesday, June 22, 2005

New feature - Mailing list

Send email to mailto:dotnet@osypchuk.com?Subject=Subscribe to recieve new post updates for this blog.
[mailto:dotnet@osypchuk.com?Subject=Unsubscribe to unsubscribe]

Typed Dataset as system state storage [Coding]

I have already covered simple appSettings in http://dotnet.osypchuk.com/2005/06/configuration-files-mapping-to-code.html. Let's talk about complex tasks.

Task definition

It is common that you need to configure application, for our example lat's see on data importer which related to a lot of structured data - it could be information where to get files, whic properties of files are (encoding, csv, delimiter, Include headers, etc), and column information - dataType, validation rules, action on errors, etc.

We can divide all this data in 3 tables:

  • Files
  • ParsingRules
  • Columns

[This is just example, I'm not insisting that this is correct for you]

Fastest way to create, maintain and use such data is to use Typed Dataset:

  • Structure of data build in visual way - fast and clear
  • Editor for data built-in visual studio
  • Generated code Typed DataSet provide a nice way to access data from a code.
  • It is easy to add feature for application to change it configurastion data

Just 4 simple steps to configure your component visually:

1. Create Typed DataSet

Add Typed dataset and define all Elements in it. It is about 10-20 minutes depending on your task complexity.

2. Create Data File

This small sep is not covered with VS.NET. You can:

a) create initial xml from code:

new ImportDataset().WriteXml("out.xml");

b) Add new xml file and add one line manually:

(Second line should be added)

3. Fill dataset with data using table-like editor:

Open DataSet - it is required to make sure that VS.NE knew scheme before opening xm file to show it correctly.

Open your xml file - even for this 2 strings you will get a table list and column information, also it uses relations and allow easily to add data for child table.

Enter data and press save when completed. After 2 minutes you have such xml - http://dotnet.osypchuk.com/Sources/ImportCfg.xml [1k]

4. Code

ImportDataset id = new ImportDataset();
id.ReadXml("ImportCfg.xml");
foreach(ImportDataset.FileRow row in id.File.Rows)
ImportFile(row);

Full source code:

http://dotnet.osypchuk.com/Sources/Osypchuk.DataSetCfgExample.zip [10k]


Applies to all dotnet languages: C#, VB.NET, C++.NET, J#
Written on C#

Tuesday, June 21, 2005

How to return WebService Exception [Q&A]

Question was:

vWhat is the best way to return an error from webservice? Can I simply throw the exception in my service or do I have to do some work to package the error message into the SOAP return?

Answer:

Only possible way to pass exception is to build SOAP Exception and to generate XML which contains all necessary info - Type of exception, message, fields. Actually, in general case you need wrapper in EVERY WebMethod:

[WebMethod]
public void Method()
{
try { /* code here */ }
catch (Exception e)
{
throw ExceptionWrapper.WrapException(e); }
}
Warning:

For some reason, Application.OnError event do not invoked for WebServices.

Some code fragments concentrated on wrapping/unwrapping Exception properties to xml which I hope could be helpful and includes example of custom WrapException method:

http://dotnet.osypchuk.com/Sources/WsExceptionsClues.txt

The same technics could be used for any dotNet language - VB.NET, C#, or J#.

Update: Thanks to Martin Bohm [http://www.theserverside.net/user/userthreads.tss?user_id=587623]

It is possible to catch all exceptions in one place by Soap extenson, more details on

http://www.codeproject.com/aspnet/ASPNETExceptionHandling.asp


Applies to all dotnet languages: C#, VB.NET, C++.NET, J#

Dan Fernandez's Blog : VB's *My* for C# Developers - Simplyfying life for developers ?

VB.NET 2005 wil have a feature called My.

Using "My", you can write code like this:

Dim
contents As String
contents =
My.Computer.FileSystem.ReadAllText("c:\mytextfile.txt")

Instead
of this:

Dim contents As String
contents =
IO.File.ReadAllText("c:\mytextfile.txt")


Dan Fernandez's Blog : VB's *My* for C# Developers

Idea is that it is simple- new people do not have idea that IO namespace exist.

I could see a lot of efforts in .NET 2.0 to "simplify" life for starter programmers. It just helps to build simple applications but not complex system. It make more complex to support code reuse. Could developer in any way customize how file is opened when using 'My'?

And what is worse, all such simple thing becomes industrial standards.

And when you start to build complex system first thing you faced that you should prove to team members that practices which are called new could not be used because it not compatible with lot concepts of code reuse.

Sometimes seems that Microsoft wants to make users from most of programmers and I do not like this.

Public Constructors are Evil [Articles]

Yes, I'm not joking.
I have only one, but very serious reason:
In most cases rejecting of public constructors will greatly increase reuse
of your code.
I'll try to explain my point of view in next few minutes.
In OO world we could have inheritance and this is widely used and lovely by many of us feature. we happy to override base methods and change behavior of class. However, for constructors in ANY language we do not have a possibility to make it virtual. If someone wrote something like this:

Button btn = new Button();

Later you could not change anything - you need to rewrite it in all places. The best is situation where you could change source code, but if it is used in many different projects, cost of performing changes increases greatly, because you need to check compatibility with other projects.

Even Microsoft in Windows Forms Generators shows for us a very bad example - it uses public constructors. Have you ever tried to change all buttons from one type to another?

Another good point of public constructor boycott: every team member start to think in terms of factories. When component has a factory and way to change it, you have a way to completely modify classes which are constructed by component.

Every component should have a factory with virtual methods for each class - constructor pair (In case if more than one constructor required). And it should be simple and clear way to change this factory - in simplest case it could be read/write singleton, but it is component dependent and could be solved in different ways with different benefits. Good to have a parameter in each of factory method which could be used to describe context - thus in future it makes possible for factory to make a decision which object to build. [If you interested, i can talk about in another article]

Real life workarounds

Life starts to make surprises in places where dotNet automatic uses of constructors. It requires from code to have accessible public constructors - for remoting and for Web Services.

I suggest to use ObsoleteAttribute to keep source code clean from public constructors. It shows mistaken usage of members, marked obsolete at compile time, and allows for dotnet use it.

Second parameter in ObsoleteAttribute constructor is 'error' which shows compile time error, if this constructor used. Do not use this for webservices! You code will compile fine. At runtime, dotnet generates code based on .asmx file and then compiles it using compiler and you receive very strange error only when trying to execute method which uses such class as parameter or result. [HTTP error 500 - Internal server error, but on server side all will be clear]

Also could be helpful to know that reflection allow to call a constructors with ObsoleteAttribute even with Error=true.

Exceptions

In every rule there are exceptions. And this rule also has it. At least, you need public constructors for Attributes. Mostly it is not a problem to use it for exceptions, etc.

Welcome to world without public constructors - I'm looking forward for your feedback.

Monday, June 20, 2005

Blog Content

REPLACER

Configuration files - mapping to code [Coding]

Introduction

I'm going to show another way where each appConfig key maped to class property. What we have from Microsoft to use configuration files:
  • Simple application configuration section, accessible via ConfigurationSettings class
  • Configuration Sections

In small applications, usually you are going to use 1st scenario.

Problems:

  • Impossible to track on start of application if all necessary information specified correctly.
  • Need to define a string constants for keys

I'm going to show a managed way to avoid both of these disadvantages and not using Configuration sections.

Goal

Idea is to use get a native class with properties mapped directly to configuration file and to put all dirty work to reflection and attributes.

Implementation

Source code with example is here - ConfigurationSolution.zip

ConfigurationHelper and attribute - Osypchuk.Configuration\ConfigurationHelper.cs

Derived class which define all keys as properties - Osypchuk.Configuration.TestConsole\Configuration.cs

Usage example - Osypchuk.Configuration.TestConsole\Main.cs

I have defined class Configurattion and uses ConfigKeyAttribute to apply it to every get method of properties. Base class looks for this attribute using StackTrace.

On loading, all class properties marked ConfigKeyAttribute with Mandatory = true checked to ensure it exist in config file.

Warning:

Virtual on each property is mandatory. Otherwise compiler generates get as inline. This causes that we would not be able to find ConfigKeyAttribute in stack trace.

Also please note that get method of property is marked with attribute, not property.


Applies to all dotnet languages: C#, VB.NET, C++.NET, J#

Visual Studio.NET Solution Structure Guide [Articles]

Overview

Goal of solution is to organize all what is related to particular project into single entity. This is really important because of:
  • Source control requirements
  • Simplify compilation
  • Simplify testing
  • Simplify installation/deployment

As we can see, all this is about collaboration. While expecting Visual Studio 2005, we can add some tricks which makes our life more organized even with "old" Visual Studio 2002/2003.
I'm going to describe following topics related to solution:

  • 3rd Party components
  • Project related incoming documents
  • Web Service References

Pre-requirements

I'm suggesting that all projects (including web projects) is in subfolders from solution root.

3rd Party components

It's common to use 3rd parties - Exception management AppBlocks, DataAccess, NUnit.Framework, GUI libraries, etc. Important questions for us will be:

  • Avoid, if possible, manual installation on every development PC
  • Synchronize versions
  • Store correct version in source control

In VS.NET when you add reference to another assembly, this is your problem to distribute it to another PC.

Let's create an empty project in our solution, name it. Copy all necessary .dll files into folder under this project. You could create subfolders if you wish. After this you could add this files to your project. (Files, not references!). You should get something like this:

We got:

  • All developers uses same libraries.
  • Distribution/Upgrading of 3rd party libraries is possible via source control (if it do not require full installation)
  • 3rd party libraries are in source control together with project source

Project related incoming documents

The same idea could be used to bind project documents to a source code. It is good to organize documents by project stages (Inception, Planning, Development, etc) and/or by Internal/External.

Our benefit is versioning - we could always review history of document changes. However, noone source control able to show for us differences between MS word documents.

In case when you need to share this documents with customer which do not has an access to you source database, you could setup web project for this. VS.NET has a relatively good ability to publish web projects. Only thing you need to do - is to create simple index file, or a write .aspx page which generates list of all documents in subfolders. It would not took more than few hours.

Web Service References

I was developing a complex system which used web services technology to exchange data. I would like to share one small hint from my experience.

This is very good practice to use a separate assembly for web references generated by VS.NET. In other words, you need one logical entry point.

After a while, you could find out that many different modules of your system need access to web service. If you place web reference in each of them you will be faced few problems:

  1. You will need to update every of them every time web service changed
  2. You will be not able to cast type from one web service wrapper to another

Such simple solution as one assembly for web services help you to build solid system - especially when you are developing both service and client and something started to change.

Also in solution...

Definetely, there are a lot more things which could be placed in solution, but it seems to be more common experience so I not mentioned it. At lease it should also include database objects if any, unit tests, source code documentation, automatical build scripts, photos from last company party, etc.

Applies to all dotnet languages: C#, VB.NET, C++.NET, J#