Saturday 21 November 2009

Great article about memory leaks in .NET application

When digging more information about GDI resource leaking I have found nice article which describes what memory leaks can be found in .NET applications and how to avoid them. The article also shows what tools can be used to find different kinds of leaks. Here is the link How to detect and avoid memory and resources leaks in .NET applications.

Tuesday 17 November 2009

GDI objects leaking and its prevention

Everyone who is developing WinForms applications can find out that his application starts in some point have problem with raising GDI objects count. Usually developers who use some high-level programming language (in my case c#) don't think they should care about releasing some low-level objects such as GDI objects but it's not true. It can happen that the application which is opening a lot of forms, creating its forms dynamically etc. will start to be slow and after some time even unusable.

What are GDI objects for?

Among GDI objects belong Bitmap, Brush, DC, Font, Palette and some other objects (see full list in the link section). These objects are used for visualization of UI of applications in Windows. Each version of Windows has maximum number of GDI objects which can be created in the moment (e.g. WinXP has default of 10000 objects set). The max number can be set in Windows registry. The actual amount of created objects per application can be displayed in task manager (show GDI objects column settings).

What is the problem?

Each time the application needs to show new form, GDI objects are created and if they are not properly disposed then their amount is raising, consuming memory and windows kernel starts to have problem with redrawing forms, creating new forms and whole system slows down.

What can developer do to prevent GDI objects count raising?

Developer should make sure that Dispose() method is called on all disposable objects. The biggest problem is when the form content is composed dynamically then Dispose() method needs to be called manually on all dynamically created controls. When application shows non-modal forms (use form.Show()) then developer doesn't need care about calling Dispose() method. But if the application shows modal dialogs (use dlg.ShowDialog()) then Dispose() needs to be called manually to free up created GDI resources.

Links:

GDI Objects on msdn
GDI on wikipedia
Detecting GDI user handler leaks in WinForms
Detect and Plug GDI Leaks in Your Code with Two Powerful Tools for Windows XP
GDI memory leak in Windows Forms

Tuesday 12 May 2009

CSLA.NET introduction - First business object

I have decided to learn about CSLA.NET framework and write down couple of articles which can help to understand the purpose of the framework and what it can do for you. I have learned basics but the framework has very nice features so it forces me to learn more.

What CSLA.NET is and what it can do?

CSLA.NET is framework which helps you to use business objects to build efficiently various types of application and enables to use object-oriented design in a distributed computing environment.

CSLA.NET framework helps developer to:
  • support for databinding in Windows and Web Forms
  • support for many types of UIs based on the same business objects
  • management of validation rules
  • management of authorization rules
  • N-level undo on a per-object basis (edit, cancel, apply)
  • interaction with distributed transaction technologies

Example

There will be created simple application which will show basics of the framework. In the first part the goal will be to create Customer class which will support databinding, contain validation rules, support undo functionality and use LINQ for access to database. Later I will continue with the example, add autorization, other classes and relation between them etc.

Business objects in CSLA.NET needs to be serializable objects and their properties, methods are usually divided into following categories:
  • Business methods
  • Factory methods
  • Validation rules
  • Authorization rules
  • Data access
The definition of the Customer class will looks like:
[Serializable]
public class Customer : BusinessBase<Customer>
As I have said before, business object are marked as serializable and are usually derived from some CSLA.NET base class (in our case BusinessBase).

Business methods

#region Business Methods

private byte[] timestamp = new byte[8];

private static PropertyInfo IdProperty = RegisterProperty(p=>p.Id, "Customer Id");
///
/// Read only property - primary key and unique
///

[System.ComponentModel.DataObjectField(true, true)]
public int Id
{
get { return GetProperty(IdProperty); }
}

private static PropertyInfo FirstNameProperty = RegisterProperty(p=>p.FirstName, "First Name");
///
/// Read write property
///

public string FirstName
{
get { return GetProperty(FirstNameProperty); }
set { SetProperty(FirstNameProperty, value); }
}

private static PropertyInfo LastNameProperty = RegisterProperty(p=>p.LastName, "Last Name");
public string LastName
{
get { return GetProperty(LastNameProperty); }
set { SetProperty(LastNameProperty, value); }
}

#endregion
Customer class has three public properties. It contains Id as unique identifier and you can see it is read-only property. It is decorated with DataObjectField attribute which shows the field as unique primary key. The attribute can help during databinding but it is not mandatory.
RegisterProperty method indicates that the field belongs to the business object type. GetProperty method retrieve value of the property but at first it check access rights.
Customer class contains also FirstName and LastName property, which are read-write properties. I will only mention SetProperty method which at first check access rights and after that sets new value. It throws an exception when user is not allowed to change the value.
Timestamp property holds database timestamp and is used for optimistic concurrency.

Factory methods

#region Factory Methods

public static Customer NewCustomer()
{
return DataPortal.Create();
}

public static Customer GetCustomer(int id)
{
return DataPortal.Fetch(new SingleCriteria(id));
}

public static void DeleteCustomer(int id)
{
DataPortal.Delete(new SingleCriteria(id));
}

private Customer()
{ /* Require use of factory methods */ }

#endregion
There is not usually used constructor to create instances of object in CSLA.NET. Instead of that there are used factory methods to create (NewCustomer method), retrieve (GetCustomer method) or delete (DeleteCustomer method). You can see above that there is actually called DataPortal object which abstracts you from the actual data layer. There is used direct access to database in this first article about CSLA.NET but you can use easily e.g. WCF, web services, .NET remoting etc. just by configuring your application.

Validation rules

#region Validation Rules

protected override void AddBusinessRules()
{
ValidationRules.AddRule(CommonRules.StringRequired, FirstNameProperty);
ValidationRules.AddRule(CommonRules.StringMaxLength,
new CommonRules.MaxLengthRuleArgs(FirstNameProperty, 50));

ValidationRules.AddRule(CommonRules.StringRequired, LastNameProperty);
ValidationRules.AddRule(CommonRules.StringMaxLength,
new CommonRules.MaxLengthRuleArgs(LastNameProperty, 50));
}
The big advantage of CSLA.NET is that object holds its own validation rules. In our case you can see that e.g. FirstName property is required and at maximum 50 characters long. You can specify any validation rules you need. Validation rules are check when the property is changed or by calling ValidationRules.CheckRules() manually.

Autorization rules

They allows to say who is able to read/write class properties and also who can create/edit/delete objects of specified type. There are no authorization rules specified in this first demo. If no rules are specified then it means that everyone can do everything.

Data access

#region Data Access

[RunLocal()]
protected override void DataPortal_Create()
{
LoadProperty(IdProperty, IdProperty.DefaultValue);
LoadProperty(FirstNameProperty, string.Empty);
LoadProperty(LastNameProperty, string.Empty);

ValidationRules.CheckRules();
}

private void DataPortal_Fetch(SingleCriteria criteria)
{
using (var ctx = ContextManager.GetManager(CSLADemo.DalLinq.Database.CSLADemo))
{
// get project data
var data = (from p in ctx.DataContext.Customers
where p.Id == criteria.Value
select p).Single();

LoadProperty(IdProperty, data.Id);
LoadProperty(FirstNameProperty, data.FirstName);
LoadProperty(LastNameProperty, data.LastName);

timestamp = data.LastChanged.ToArray();
}
}

[Transactional(TransactionalTypes.TransactionScope)]
protected override void DataPortal_Insert()
{
using (var ctx = ContextManager.GetManager(CSLADemo.DalLinq.Database.CSLADemo))
{
// insert project data
System.Data.Linq.Binary lastChanged = null;
int? newId = null;
ctx.DataContext.addCustomer(
ReadProperty(FirstNameProperty),
ReadProperty(LastNameProperty),
ref newId,
ref lastChanged);

timestamp = lastChanged.ToArray();
LoadProperty(IdProperty, newId);
// update child objects
FieldManager.UpdateChildren(this);
}
}

[Transactional(TransactionalTypes.TransactionScope)]
protected override void DataPortal_Update()
{
using (var ctx = ContextManager.GetManager(CSLADemo.DalLinq.Database.CSLADemo))
{
// insert project data
System.Data.Linq.Binary lastChanged = null;

ctx.DataContext.updateCustomer(
ReadProperty(IdProperty),
ReadProperty(FirstNameProperty),
ReadProperty(LastNameProperty),
timestamp,
ref lastChanged);

timestamp = lastChanged.ToArray();
// update child objects
FieldManager.UpdateChildren(this);
}
}

protected override void DataPortal_DeleteSelf()
{
DataPortal_Delete(new SingleCriteria(GetProperty(IdProperty)));
}

private void DataPortal_Delete(SingleCriteria criteria)
{
using (var ctx = ContextManager.GetManager(CSLADemo.DalLinq.Database.CSLADemo))
{
ctx.DataContext.deleteCustomer(criteria.Value);
}
}

#endregion
There can be overriden several BusinessBase method for data access. In our case there is used LINQ and stored procedures (instead of fetch method). You can see RunLocal attribute for DataPortal_Create method which means that when the business object is created e.g. by web service then it will not call web service but creates the object locally.
The other methods are quite standard but you can see another interesting feature of CSLA.NET and that's how it handles transactions. For you as developer it is enough to decorate method with Transactional attribute and method will run as transaction.

Conclusion

There is described how to create single business object in the article but you may be interested what to do after you create it. I think the best is to download source codes of the example and study them a bit. I have choosen win forms GUI for the application but the advantage of the CSLA.NET is that you can use same business objects with any interface you like (web, WPF).

Source code

Source codes are available here source code. Zip file should contain everything you need to build the source codes (VS 2008 solution, sql express example database, rebuilt SCLA.NET binaries). You only need to have installed VS 2008 SP1 and sql express database engine on your computer.

References

Monday 4 May 2009

NUnit 2.5.0 installation problem

I was trying to install NUnit msi package on my computer but the installer told me this: "Please wait while installer finishes determining your disk space requirements.". It hanged forever so I finished intallation. I thought some other running program probably blocks intallation for some reason. I tried to kill some running processes (IE 7.0, Firefox, MS Outlook) and run the installer again with success. I am not sure what exactly happened but it helped at least in my case.

Monday 27 April 2009

How to uninstall MSSQL server 2008

I have had into some troubles with my computer and I wanted to reinstall MSSQL server 2008 but I was not able to find out how to unintall it. Here is the command which will do it for you:
"c:\Program Files\Microsoft SQL Server\100\Setup Bootstrap\Release\x86\SetupARP.exe" /x86

Tuesday 21 April 2009

Tortoise SVN 1.6.0 not compatibile with AnkhSVN 2.0

Recently I was forced to reinstall Windows and also Visual Studio 2008. I wanted to intall latest versions of TortoiseSVN and AnkhSVN 2.0 but the versions are not compatible.

There are two possible solutions:
1. download and install daily build of AnkhSVN 2.0 (stack overflow),
2. if you for some reason do not want to install daily build then there is possible to install TortoiseSVN 1.5.9 which is compatible with stable version of AnkhSVN.

Monday 20 April 2009

Mocking in C#

During my last assignement I worked on refactoring of our project and part of that was to refactor our test. I find out that we use mocks in there. To be more specific we used Rhino Mocks. I was curious how it works, what are advantages/disadvantages and wanted to learn more.

What are mocks (mock objects)

Mock objects are special testing objects which allow developers to test in easier way the behavior of real objects. Classical unit test tests rather the state of objects then their behavior. This is probably the biggest difference between those two test approaches.

For better understanding of differences, there are used and a bit modified examples from Martin Fowler's article. The examples are adapted for .NET environment.

For testing there are used following classes:
IWarehouse interface
public interface IWarehouse
{
int GetInvetory(string name);
void Add(string name, int count);
bool HasInventory(string name, int count);
void Remove(string name, int count);
}
WarehouseImpl class
public class WarehouseImpl : IWarehouse
{
private Dictionary store = new Dictionary();

public int GetInvetory(string name)
{
if (store.ContainsKey(name))
return store[name];
else
return 0;
}

public void Add(string name, int count)
{
if (store.ContainsKey(name))
store[name] = store[name] + count;
else
store.Add(name, count);
}

public bool HasInventory(string name, int count)
{
if (store.ContainsKey(name))
if (store[name] >= count)
return true;
else
return false;
else
return false;
}

public void Remove(string name, int count)
{
store[name] = store[name] - count;
}
}
Order class
public class Order
{
private string name;
private int count;
private bool isFilled;

public bool IsFilled { get { return isFilled; } }

public Order(string n, int c)
{
name = n;
count = c;
isFilled = false;
}

public void Fill(IWarehouse warehouse)
{
if (warehouse.HasInventory(name, count))
{
warehouse.Remove(name, count);
isFilled = true;
}
}
}

Classical (NUnit) test example

This is example how usually NUnit tests are written and as you can see there we do some actions (order.Fill()) and check that results are as expected.

[TestFixture]
public class NUnitTest
{
private IWarehouse warehouse;
private const string TALISKER = "Talisker";
private const string HIGHLAND_PARK = "Highland Park";

[SetUp]
public void Setup()
{
warehouse = new WarehouseImpl();
warehouse.Add(TALISKER, 50);
warehouse.Add(HIGHLAND_PARK, 25);
}

[Test]
public void TestOrderIsFilledIfEnoughInWarehouse()
{
Order order = new Order(TALISKER, 50);
order.Fill(warehouse);
Assert.IsTrue(order.IsFilled);
Assert.AreEqual(0, warehouse.GetInvetory(TALISKER));
}

[Test]
public void testOrderDoesNotRemoveIfNotEnough()
{
Order order = new Order(TALISKER, 51);
order.Fill(warehouse);
Assert.IsFalse(order.IsFilled);
Assert.AreEqual(50, warehouse.GetInvetory(TALISKER));
}
}

Rhino Mock example

This code shows how to use Rhino.Mocks to test behavior is as expected.

[TestFixture]
public class RhinoTest
{
private const String TALISKER = "Talisker";

[Test]
public void TestFillingRemovesInventoryIfInStock()
{
Order order = new Order(TALISKER, 50);
MockRepository mock = new MockRepository();
IWarehouse warehouseMock = mock.CreateMock();

Expect.Call(warehouseMock.HasInventory(TALISKER, 50)).Return(true).Repeat.Once();
Expect.Call(delegate { warehouseMock.Remove(TALISKER, 50); }).Repeat.Once();

mock.ReplayAll();
order.Fill(warehouseMock);
mock.VerifyAll();
Assert.IsTrue(order.IsFilled);
}

public void TestFillingDoesNotRemoveIfNotEnoughInStock()
{
Order order = new Order(TALISKER, 51);

MockRepository mock = new MockRepository();
IWarehouse warehouseMock = mock.CreateMock();

Expect.Call(warehouseMock.HasInventory(TALISKER, 51)).Return(false).Repeat.Once();

mock.ReplayAll();
order.Fill(warehouseMock);
mock.VerifyAll();
Assert.IsFalse(order.IsFilled);
}
}

Differences between NUnit test and test which uses Rhino.Mocks

As you can see in the examples above, mocking can help you to test easier in cases you do not want your unit tests e.g. access database, send real emails etc. You only test the behavioural of the classes you are insterested in.

References

Mocks aren't stubs by Martin Fowler
NUnit
Rhino.Mocks

Saturday 7 February 2009

How to remove diacritics in C#

Sometimes it is useful to work with the text without diacritics. How to do it properly in .NET is well described in the following post How to remove diacritics (written in Czech).