Category Archives: .NET World

Sample Quiz on Delayed Execution of IEnumerable

A sample quiz to test your knowledge of delayed execution of IEnumerable<T>.

Assume you have a method as follows:


public IEnumerable<AppointmentSlot> GetOpenSlots(Dictionary<string, string> request)
{
return _openSlots;
}

The above method returns a list of open slots which could simply have been a collection prepoluated when the class was constructed.

Say somewhere else in the code you call this method as follows:


public RelayCommand GetOpenAppointmentSlotsCmd
{
get { return new RelayCommand(o => true, o =>
{
OpenAppointmentSlots = _resourcesServiceClient
.GetOpenSlots(null)
.Select(s => new AppointmentSlotViewModel(s));
});}
}

Where OpenAppointmentSlots is a property of type IEnumerable<T> and T is of type AppointmentSlotViewModel which in simple form could look something like  this:


public class AppointmentSlotViewModel : ViewModelBase
{
public AppointmentSlot AppointmentSlot { get; }

public AppointmentSlotViewModel(AppointmentSlot slot)
{
AppointmentSlot = slot;
}

public DateTime StartsAt => AppointmentSlot.StartsAt;
public int DurationInMiutes => AppointmentSlot.DurationInMiutes;
public string ProviderId => AppointmentSlot.ProviderId;

public RelayCommand BookAppointmentSlot
{
get
{
return new RelayCommand(o => NotBooked, o =>
{
NotBooked = false;
});
}
}

private bool _notBooked = true;
public bool NotBooked
{
get { return _notBooked; }
set
{
SetField(ref _notBooked, value, "NotBooked");
}
}
}

Further assume you had the list of OpenAppointmentSlots bound to a ListView and had a DataTemplate which manipulated the NotBooked property of AppointmentSlotViewModel.

Now, say somewhere else in the code, perhaps in the same view model which gets the list of open slots, you attempt to submit these selected open slots for booking as follows:


public RelayCommand BookAppointmentCmd
{
get
{
return new RelayCommand(o => true, o =>
{
var booked = OpenAppointmentSlots..Where(s => s.IsBooked()).Select(nb => nb.AppointmentSlot);
BookedAppointmentStatus = _resourcesServiceClient.BookAppointments(booked);
});
}
}

After manipulating the UI such that you now have two slots booked,  what do you suppose will be the result of the variable called booked, in the above snippet and why?

 

Yet another practical pocket guide on writing clean code

Being a big proponent on crafting beautiful, robust and maintainable code, I have read several books and articles on the subject.  One of my favorite resources is a book titled “Clean Code” by Robert C. Martin.

I would propose that such a resource be readily available in the company library and would even go as far as advocating for every software engineer joining the company to either have read this book or is required to read this book as part of the on-boarding process.

In summary what is clean code:  Code which mostly abides by the SOLID principles of software design.  In my own words.

Methods should have a single responsibility.  It is better to have a class with many small methods that have a class with a small number of large methods.

Methods should not be overly long. A well known and acceptable measure is that a method should not span the entire code editor space in Visual Studio, when viewed over a 15″ laptop monitor.  For example, this is a long method:

On the otherhand, this is a nice, short and terse method:

Methods should return early if possible.  This avoid too many nested iffs.  For example, consider the following method which takes in input object of some sort

   private void InitializeActionMethods()
        {
            if (_configurationManager.Configuration == null)
            {
                Logger.Warn("Some configuration is not defined.");
                return;
            }

We fail fast and early.  In contrast, we could written the code like this:

   private void InitializeActionMethods()
        {
            if (_configurationManager.Configuration =! null)
            {
                // continue
            }

This creates a code base with too many nested-iffs which is hard to read and maintain.

Method names and variables should clearly indicate purpose.  I often say code is a story.  Write code as if you are writing a story.  Books with shorter paragraphs are more engaging than books with longer paragraphs.  I often see developers naming variables using acronyms instead of taking the time to craft out descriptive variable names. Again, if code is a story, we need to clearly identify the characters.

Entities themselves should have single responsibility.  This one is also easy to violate.  I have seem some very large and weird looking classes over the years.  I have also seen classes that are almost impossible to refactor and unit test as it is composed of a collection of large, deeply nested methods with a large number of inter-dependencies.  Keep classes small.  I have told my devs that is is better to have a code base with thousands of small entities that one with a small number of large entities.  The former system, if well organized, is easily to reason with, maintain, modular and robust.

Entities should have dependencies passed to them.  The term coined for this is dependency injection or inversion of control.  I always get confused here but the idea is for a factory to construct a car, it needs to have all of its dependent bits, such as assembly line, etc.  These must be explicit and defined up front.

Unit test, unit tests and more unit tests. I cannot emphasize this enough but any component in the system should have an associated unit test which is concise.  There are well documented strategies for crafting awesome unit test but they should abide by the AAA principle of Arrange, Act and Assert.  Google this. Also, make these test very easy to follow.  All dependencies should be arranged or created up front.  if you are resolving entities from some container somewhere, which includes configuring some sort of logger, which requires some additional piece of configuration somewhere, you probably need to step back and rethink your tests and class design.

Code should be closed for modification and open for extension, as stated in the Open/Closed Principle, code should be easy to extend but closed for modification.  This is a tough one but think if it this way.  If you start creating code with long switches, then it is time to sit back and think of some patterns to use.

Code should be robust against anomalies but at the same time need not be overly micro-optimized.  Beautiful code means that it is easy on the eye, easy on the mind, free flowing, yet robust against extremities.  This includes excellent exception handling and logging.

Happy Coding.

Be on lookout for StackExchange Redis ConnectionMultiplexer ConnectionFailed event misfires

We are using the StackExchange.Redis ConnectionMultiplexer class to manage our connections to Redis.  Without clear guidance from the documentation, we have attempted to create our own retry strategy with this client with code which looks like this:

 

  public RedisClient()
 : this(GetConnectionString())
 {
 }
 
 public RedisClient(string connectionString)
 {
 _logger = LogServiceProvider.Instance.GetLogger(GetType());
 _connectionString = connectionString;
 MaxRetryAttempts = 10;
 DelayBeforeRetryInMillisecs = 500;
 InitializeConnection();
 }

 private void InitializeConnection()
 {
 _logger.Info("Initializing a connection to the Redis cluster. ");
 bool isReconnectionAttempt = false;

 if (_connectionMultiplexer != null)
 {
 Debug.WriteLine("disposing " + _connectionMultiplexer.GetHashCode());
 _connectionMultiplexer.ConnectionFailed -= HandleConnectionFailedEvent;

 // test this change.....
 _connectionMultiplexer.Close(false);
 isReconnectionAttempt = true;
 _logger.Info("This is reconnection attempt to the Redis cluster.");
 }

 _connectionMultiplexer = ConnectionMultiplexer.Connect(_connectionString);
 _needConnect = !_connectionMultiplexer.IsConnected;
 _connectionMultiplexer.ConnectionFailed += HandleConnectionFailedEvent;

 Debug.WriteLine("created " + _connectionMultiplexer.GetHashCode());

 if (!_needConnect && isReconnectionAttempt)
 {
 _logger.Info("Reconnection to the Redis cluster was succeeded.");
 RaiseRedisConnectionReestablished();
 }

 if (!_needConnect)
 {
 _logger.Info("Connection is successfully established to the Redis cluster.");
 }
 else
 {
 _logger.Error("Cannot establish a connection to the Redis cluster. ");
 }
 }

 private void HandleConnectionFailedEvent(object sender, ConnectionFailedEventArgs args)
 {
 // we could potentially receive multiple of these events so we need to be be careful
 Debug.WriteLine( "received connection failure event from " + sender.GetHashCode());
 Debug.WriteLine(" multiplexer id is " + _connectionMultiplexer.GetHashCode());

 // There's a known issue with the Redis ConnectionMultiplexer which prevents if from 
 // completely releasing an event handler even after it has been disconnected and disposed.
 // Se we need the following line of code.

 if (sender.GetHashCode() != _connectionMultiplexer.GetHashCode())
 return;

 _logger.Error("Connection to the Redis cluster has failed with the following event arg:", args.Exception);

 RaiseRedisConnectionFailed(args.Exception);
 AttemptReconnection(1);
 }

 private void AttemptReconnection(int trial = 1)
 {
 if (trial == MaxRetryAttempts)
 {
 _logger.Info("Have attempted to re-connect to the Redis cluster 3 times. Aborting.");
 
 return;
 }

 if (_connectionMultiplexer.IsConnected)
 {
 _logger.Info("Connetion to Redis cluster is no longer required.");
 return;
 }

 _logger.InfoFormat("Attempting reconnection attempt {0} to the Redis cluster.", trial);
 RedisReconnectionAttempt(this, new RedisReconnectionAttemptEventArgs(trial));

 // wait for a few seconds and then try to reconnect.....
 Thread.Sleep(DelayBeforeRetryInMillisecs);
 InitializeConnection();

 trial = trial + 1;
 TotalNumberOfReconnectionAttempts = TotalNumberOfReconnectionAttempts + 1;
 AttemptReconnection(trial);
 
 }

When a network drop is simulated, the ConnectionFailed event is fired as expected. When this happens, an attempt is made to dispose of the current instance of the ConnectionMultiplexer object and create a new one. We do this to avoid the situation where attempting to access the current ConnectoinMultiplexer instance throws an exception indicating the object has already been disposed.

So we dispose the current instance, or atleast we think we do and create a new one. Yet somehow, the original instance which experienced the network drop, but is now disposed, still manages to fire ConnectionFailed events even though we are no longer supposed to be listerning.  After all, we unsubscribed to the event as indicated in the InitializeConnection method above.

I could not get an answer from StackOverflow. I also could not determine the cause just by looking at the source code for this ConnectionMultiplexer class.  What I could do, however, is put in a small hack to ensure these multiple noisy events are ignored, unless they are coming from the correct ConnectionMultiplexer instance.

I even have test to ensure my hack works.

Happy coding.

Some defensive coding practices against environmetal uncertainties – part 1

1. Always consider Environment.CurrentDirectory as opposed to Assembly.GetExecutingAssembly().Location, when getting current working directory.

This innocent looking line of code causes grief.

var pathToSqliteDatabase = Path.Combine(Assembly.GetExecutingAssembly().Location, "SqliteDb.db3");

Why?

Let’s just first ignore the fact that a test harness should be going directly to a database since this is part of the problem. But if you are running a test harness that has to resolve a location to an SQLite database instance you will get interesting results.

If using MSTest, the above line of code resolves to the current test project’s working folder. So if your test project was in c:\dev\SQliteAdventures, pathToSqliteDatabase to be

c:\dev\SQliteAdventures\bin\Debug

However, if you decided to change to NUnit and have ReShaper installed, the same above line of code now resolves to some random location:

In my case, it looked like this:

C:\Users\knji\AppData\Local\Temp\jahvgmug.pjb\s5hvswgs.kil\SQliteAdventures\assembly\dl3\086a6c5d\1860476f_4375d001\

Changing the above line of code to

var pathToSqliteDatabase = Path.Combine(Environment.CurrentDirectory, "SqliteDb.db3");

will return the current result regardless of the operating environment. So this is preferable here.

2. Carefully consider using x86 vs x64 versions of 3rd party dependencies.

The System.Data.SQLite.dll .NET connector for SQLite, for example comes, with an x86 and x64 version. When executing tests using MSTest, x86 version of the is required since the MStest runner executes within the 32 bit Visual Studio process. However, if you are running NUnit via ReSharper, which executes within its own 64 bit process called JetBrains.ReSharper.TaskRunner.CLR45.x64.exe, you need the x64 bit version of this dll otherwise you get image loading exception. Besides testing against abstractions or fakes, I do not yet know to automate this. Ideas always welcomed.

To be continued…..

Windows Phone Listbox: ensure ItemSource is bound before SelectedItem

Just spent a couple of hours trying to figure out why setting the SelectedItem of a ListBox kept crashing the application. It turns out that setting the ItemSource binding before the SelectedItem is a no go as per this StackOverflow posting.

So beware when designing your Windows Phone pages. For example, look at the snippet below.

 <toolkit:ListPicker            
            Header="Select a stop"
            Margin="{StaticResource PhoneMargin}"
            Grid.Row="2" 
            Grid.Column="0"
            SelectionMode="Single"
             ItemsSource="{Binding Stops}"
            SelectedItem="{Binding SelectedStop, Mode=TwoWay}">

If you place SelectedItem before ItemSource application will crash when you attempt to programmatically set the SelectedItem.

Implement pub-sub with RabbitMQ in 15 minutes

In publish/subscribe all subscribers get a copy of all published messages. A complete implementation of pub/sub using RabbitMQ follows:

Mandatory Setup

1. Download and install Erlang. RabbitMQ Server is written in Erlang.
2. Download and install the RabitMQ Service broker, which is a windows service.
3. Ensure service is running on its default port 5672.

Complete instructions for downloading and installing RabbitMQ on Windows is found here.

Create Producer and Consumer
4. Create a new Console project called RabbitMQProducer.
5. Using NuGet, add a reference to the C# RabbitMQ binding called RabbitMQ.Client.
6. Modify the content of the Program class using the following code:

  public class RabbitMqPublisher
    {
        public static void Main()
        {
            var factory = new ConnectionFactory() {HostName = &quot;localhost&quot;};
            const string exchange = &quot;authentictions&quot;;

            //The connection abstracts the socket connection, and takes care of protocol version negotiation and authentication and so on for us.
            using (var connection = factory.CreateConnection())
            {
                using (var channel = connection.CreateModel())
                {
                     //1. declare and exchange were messages will be sent to
                    channel.ExchangeDeclare(exchange, &quot;fanout&quot;);

                    while (true)
                    {
                        var stopWatch = new Stopwatch();
                        stopWatch.Start();

                        //2. create a message, that can be anything since it is a byte array
                        for (var i = 0; i &lt; 1000; i++)
                        {
                            SendMessage(channel,
                                string.Format(&quot;{0}: msg:{1} hello world &quot;, DateTime.UtcNow.Ticks, i));
                            Thread.Sleep(10);
                        }

                        stopWatch.Stop();
                        Console.ReadLine();

                        Console.WriteLine(&quot;====================================================&quot;);
                        Console.WriteLine(&quot;[x] done sending 1000 messages in &quot; + stopWatch.ElapsedMilliseconds);
                        Console.WriteLine(&quot;[x] Sending reset counter to consumers.&quot;);

                        SendMessage(channel, &quot;reset&quot;);
                        Console.ReadLine();
                    }
                }
            }
        }

        private static void SendMessage(IModel channel, string message)
        {
            var body = Encoding.UTF8.GetBytes(message);

            //3. send the message
             channel.BasicPublish(exchange, string.Empty, null, body);

            Console.WriteLine(&quot; [x] Sent {0}&quot;, message);
        }
    }
}

6. Compile and run the program and you should see each message being set written to the console.
7. Create a new C# Console project, called RabbitMQSubscriber and modify the Program class as
follows:

public class RabbitMqSubscriber
    {
        static void Main(string[] args)
        {
            int messagesReceived = 0;

            var factory = new ConnectionFactory() { HostName = &quot;localhost&quot; };
            using (var connection = factory.CreateConnection())
            {
                using (var channel = connection.CreateModel())
                {
                     //1. declare and exchange were messages will be sent to
                    channel.ExchangeDeclare(exchange, &quot;fanout&quot;);

                    //2. create a non-durable, exclusive, autodelete queue with a generated name
                    var result = channel.QueueDeclare(); 

                    //3. bind to the exclusive queue created above
                    channel.QueueBind(result.QueueName, exchange, string.Empty);
                    
                    //4. now get message from queue
                    var consumer = new QueueingBasicConsumer(channel);
                    channel.BasicConsume(result.QueueName, true, consumer);

                    Console.WriteLine(&quot; [*] Waiting for messages.&quot; +
                                        &quot;To exit press CTRL+C&quot;);
                    while (true)
                    {
                        var ea = consumer.Queue.Dequeue();

                        var body = ea.Body;
                        var message = Encoding.UTF8.GetString(body);
                        messagesReceived += 1;

                        Console.WriteLine(&quot;[x] {0} Received {1}&quot;, messagesReceived, message);
                        if (string.CompareOrdinal(&quot;reset&quot;, message) == 0)
                        {
                            messagesReceived = 0;
                        }
                    }

                }
            }
        }
    }

8. Using NuGet, add a reference to the C# RabbitMQ client binding, called RabbitMQ.Client to resolve compilation problems.

9. Compile and run the program. If you have the Producer already running, you may have to
right click on the consumer project and select Debug | Start new instance.
10. Run an instance of the publisher and multiple subscribers and notice that all subscribers get a copy of the messages being produced.

Some notes about the implementation:
1. You can fire up more than one publisher and they will all send messages to the exchange.
2. You can fire up one or more listeners and they will all retrieve messages from the exchange.
3. In this exercise, messages are not durable, in the sense that if there are no subscribers, they are lost.
4. Every subscriber gets a copy of every message.
5. RabbitMQ just works as advertised. I am very impressed with the framework.

Use case
This can be used in a scenario where you have field data and have a bunch of processing stations. Each processing station gets a copy of field data so it can perform a different set of business rules.

For example, authentication events could be shared among multiple subscribers. One of such could log these messages to a database. Another could take the events and do some heuristics including machine intelligence.