binary dreams

a world of 1s and 0s

How to use C# properties with SOLID class design principles

It wasn't so long ago I was using properties without any consideration to how they SHOULD be used. I'm going to show you how you can use them properly with the help of SOLID Class Design Principles.

It wasn't so long ago I was using C# properties without any consideration to how they SHOULD be used. I'm going to show you how you can use them properly with the help of SOLID Class Design Principles.

Case 1:

This is a typical class you might have written.

public class Person
{
public string Forename { get; set; }
public string Surname { get; set; }
public Person() {}
}

STOP! Using public setters here with the person attributes breaks the Single Responsibility Principle (SRP) because the class has more than one reason to change. The class breaks this with two reasons - Forename and Surname.

To fix this, make the setters of those properties private and create an Update method like so:

public class Person
{
public string Forename { get; private set; }
public string Surname { get; private set; }
public void Update(string forename, string surname)
{
Forename = forename;
Surname = surname;
}
}

Now the class has one reason to change rather than two.

In general an object should not have it's state changed unless it was changed by an action. Remember OO design is about data hiding, how an objects attribute changes is of no concern to its consumer. Only the object needs to know how it changes.

Case 2:

How would you check the object is valid? Check each property like this:

var person = new Person();
person.Update("forename", "surname");
if (person.Surname != null && person.Forename != null)
{
SaveToDatabase(person);
}

STOP! This breaks the Dependency Inversion Principle (DIP) - Depend on abstractions not on concretions. We need to create a validation method to abstract us from the attributes. The properties should not be checked outside of the class but from inside the class.

Lets rewrite it.

Create an interface

public interface IValidate
{
	bool IsValid();
}

Now change the Person class.

public class Person : IValidate
{
public string Forename { get; private set; }
public string Surname { get; private set; }
public void Update(string forename, string surname)
{
Forename = forename;
Surname = surname;
}
public bool IsValid()
{
return (Forename != null) && (Surname != null);
}
}

With the Person class rewritten you would use it like so.

var person = new Person();
person.Update("forename", "surname");
if (person.IsPersonValid())
{
SaveToDatabase(person);
}

How to configure your unsecured WCF or ASMX service for round-robin load balancing

I was asked to investigate how to get our load balancing working with our services stack. Our services stack is used by many clients, a bespoke legacy Delphi EPOS application and various internal websites.

This blog post details how to load balance using an unsecured endpoint only. To use a secured endpoint needs further investigation. In our case an unsecured endpoint was acceptable because we are not communicating outside our company network.

The load balancer

We have a Netscaler hardware load balancer configured as Round-Robin with Persistence set to None. This means each call will go to the next server and the connection to a server will not be persisted. 

Our network guy configured the load balancer to call a url every 5 minutes - in this case a service. Once called it will return the service page and it will check for specific text and as long as that happens then its successful. Doing this gives us an early warning system if a service or IIS is down and adds to the practice of zero-downtime deployments. 

Enable your WCF Service to be load balanced

Add this binding to your web.config:

<bindings>
<customBinding>
<binding name="httpBinding">
<httpTransport keepAliveEnabled="false" />
</binding>
</customBinding>
</bindings>

 If you have existing applications that use an existing endpoint, do not replace it but add the following endpoint to your web.config. 

<services>
<service>
<endpoint address="http://fakehost/fakewebsite/FakeService.svc/custom" 
contract="FakeContract.IFakeContract" binding="customBinding" 
bindingConfiguration="httpBinding" name="custom" />
</service>
</services>

How to enable your client to call a load balanced application

Add this binding to your client app.config: 

<bindings>
<customBinding>
<binding name="httpBinding">
<httpTransport keepAliveEnabled="false" />
</binding>
</customBinding>
</bindings>
Add this endpoint to your client app.config:
<client>
<endpoint address="http://fakehost/fakewebsite/FakeService.svc/FakeService/basic" 
contract="FakeContract.IFakeContract" binding="customBinding" 
bindingConfiguration="httpBinding" name="basic" />
</client>
 
Your local network admin might advise that you need to add this <bypasslist> element to a <defaultProxy>: 
<system.net>
<defaultProxy enabled="true" useDefaultCredentials="true">
<bypasslist>
<add address="10.*"/>
</bypasslist>
<proxy autoDetect="False" proxyaddress="http://fakeproxy" bypassonlocal="True" />
</defaultProxy>
</system.net>

You don't want to go via your network proxy if you don't need to. It's inefficient.

How to call a load balanced ASMX service

To call an ASMX service that is load balanced you must add the following custom binding and a similar endpoint.

<system.serviceModel>
<bindings>
<customBinding>
<binding name="HttpBinding">
<textMessageEncoding messageVersion="Soap11" />
<httpTransport keepAliveEnabled="false" />
</binding>
</customBinding>
</bindings>
<client>
<endpoint address="http://fakeserver/FakeService/Fake.asmx" 
binding="customBinding" bindingConfiguration="HttpBinding" 
contract="FakeProxyServiceReference.FakeSoap" name="CustomBinding_HttpBinding" />
</client>
</system.serviceModel>