Lazy/Poor Man’s IOC

17. February 2016 11:47

There may be times where you need IOC for nothing more than the ability to mock something for testing. In these cases you may not want to bother with all the configuration of a real IOC implementation. This ‘poor man’s’ methodology I’ve used could probably be frowned upon but it does what I need it to do in most cases (there will be use cases where this will not work).

 

The basic idea is to have either a publicly settable property or a constructor param for the concrete implementation. Then in the property getter if the backing field is null, create the ‘real’ implementation.  This allows the test cases to either set the property to a mock or pass a mock into the constructor.

 

Given these members of a controller class:

 

 

        private IConfigAccess _configDatAccess;

        private IPciMasker _pciMasker;

        private object _lock = new object();

 

        public IConfigAccess ConfigDataAccess

        {

            get

            {

                lock(_lock)

                {

                    if (_configDatAccess == null) _configDatAccess = new ConfigAccessService();

                }

                return _configDatAccess;

            }

            set

            {

                _configDatAccess = value;

            }

        }

 

        public IPciMasker PciMasker

        {

            get

            {

                lock (_lock)

                {

                    if (_pciMasker == null) _pciMasker = new PciMasker();

                }

                return _pciMasker;

            }

            set

            {

                _pciMasker = value;

            }

        }

In the unit test where you want to mock the IConfigAccess member just set the ConfigDataAccess property to the mocked object and run the test:

 

            var dacMock = new Mock<IConfigAccess>();

            dacMock.Setup(x => x.GetPciMaskByEntryPointId(epId)).Returns(GetDefaultMaskList());

 

            var controller = new ChatConversationController();

            controller.ConfigDataAccess = dacMock.Object;

           

            controller.NewMessage(item);

           

            Assert.AreEqual(expected, item.Message);

 

You just have to make sure to use the property and not the backing field. But don’t worry. If you forget a null reference exception will remind you in a hurry!

Exploring the Strategy Pattern

19. August 2015 16:09

 

According to Wikipedia the strategy pattern “is a software design pattern that enables an algorithm’s behavior to be selected at runtime.” Hmm, what the heck does that mean?

 

Let’s explore how this is implemented in the .Net Framework’s Generic List class’s Sort method. For the examples let’s use a List<Vehicle> where the Vehicle class is defined as such:

 

   1: private class Vehicle : IComparable<Vehicle> 
   2: { 
   3:     public int NumberOfWheels { get; set; }
   4:  
   5:     public string Style { get; set; }
   6:  
   7:  
   8:     public override string ToString() 
   9:     { 
  10:         return string.Format("{0}, Wheel Count = {1}", this.Style, this.NumberOfWheels); 
  11:     }
  12:  
  13:     public int CompareTo(Vehicle other) 
  14:     { 
  15:         return this.Style.CompareTo(other.Style); 
  16:     } 
  17: } 
  18:  

 

This is the collection of vehicles we’ll use:

 

   1:  
   2: private IList<Vehicle> _vehicleList = new List<Vehicle> 
   3: { 
   4:  
   5:  new Vehicle() {NumberOfWheels = 2, Style= "Motorcycle"}, 
   6:  
   7:  new Vehicle() {NumberOfWheels = 4, Style= "Sedan"}, 
   8:  
   9:  new Vehicle() {NumberOfWheels = 4, Style= "Truck"}, 
  10:  
  11:  new Vehicle() {NumberOfWheels = 3, Style= "Trike"}, 
  12:  
  13: };

 

So, calling Sort with no parameters does a default sort. In this case using the Vehicle class’s IComparable interface.

 

   1: public void SortTest()
   2: {
   3:     List<Vehicle> testList = new List<Vehicle>(_vehicleList);
   4:     testList.Sort();
   5:     foreach(var item in testList)
   6:     {
   7:         Console.WriteLine(item.ToString());
   8:     }
   9: }

 

As you expect, this sorts the list by the Style property:

 

Motorcycle, Wheel Count = 2
Sedan, Wheel Count = 4
Trike, Wheel Count = 3
Truck, Wheel Count = 4

 

Wait, where is the strategy pattern? It comes into play with the Sort method’s overloads. Let’s say we want to sort the list by the NumberOfWheels property instead. We’ll start by creating a comparer:

 

   1: private class VehicleWheelCountComparer : IComparer<Vehicle>
   2: {
   3:     public int Compare(Vehicle x, Vehicle y)
   4:     {
   5:         if (x.NumberOfWheels.Equals(y.NumberOfWheels))
   6:         {
   7:             return x.Style.CompareTo(y.Style);
   8:         }
   9:         else { return x.NumberOfWheels.CompareTo(y.NumberOfWheels); }
  10:     }
  11: }

 

Then we can pass a new instance of the comparer to the Sort method. This allows us to change the Sort method’s behavior at runtime. The Sort method doesn’t need to know anything about the Vehicle class or how to sort instances of it. It can just use the ‘strategy’ passed into it.

 

   1: public void SortTestWheelCount()
   2: {
   3:     List<Vehicle> testList = new List<Vehicle>(_vehicleList);
   4:     testList.Sort(new VehicleWheelCountComparer());
   5:     foreach (var item in testList)
   6:     {
   7:         Console.WriteLine(item.ToString());
   8:     }
   9: }

 

Now our list is sorted by Wheel Count:

 

Motorcycle, Wheel Count = 2
Trike, Wheel Count = 3
Sedan, Wheel Count = 4
Truck, Wheel Count = 4

SqlDataReader Contains Column Extension Method

30. July 2015 16:59

It seems I have to look this up a lot.  Maybe if I write it down I’ll remember! This is a slick extension method to determine if a SqlDataReader contains a column. The code is originally from this SO post.

public static class DataRecordExtensions
{
    public static bool HasColumn(this System.Data.IDataRecord dr, string columnName)
    {
        for (int i = 0; i < dr.FieldCount; i++)
        {
            if (dr.GetName(i).Equals(columnName, StringComparison.InvariantCultureIgnoreCase))
                return true;
        }
        return false;
    }

How to find ClickOnce Application Directory

21. July 2014 09:18

 

ClickOnce applications store their data in an obscure directory (i.e. C:\Users\username\AppData\Local\Apps\2.0\QH85L3CK.1O0\P6HV1J4X.59N\west..tion_945506851464d64d_0003.0002_df3408a05edbe3cf). Sometimes you want to get to this directory to take a look at a log file or check/test settings. There is an easy way to locate this directory when the application is running.

Open Task Manager

Under the Applications tab, right click the application and select go to process (or just locate the process under the Process tab if you know what it is).

Right click the process name and choose Open file location.

image

Like magic, you’ve found the obscure directory!

Auto Launch ClickOnce App From Web Page

16. June 2014 14:19

 

Recently ran into a situation where a web page was launching a ClickOnce application automatically (no interaction from the user). This worked fine on a machine running IE8, but not IE9 and greater. It would appear to download the manifest but never actually started the application without user intervention. Some research turned up a MSDN article (see the section on Activating ClickOnce Applications Through Browser Scripting) which indicates the “Automatic prompting for file downloads” under Security/Downloads needs to be enabled. Checked on the IE8 machine and sure enough it was enabled. Went to the IE9 machine, and there is no such setting! After some more researching I found a registry key to change on IE9 and greater to enable the “Automatic prompting for file downloads”:

hkcu\Software\Microsoft\Windows\CurrentVersion\internet Settings\Zones (zone 2 is trusted sites which is relevant for my companies intranet environment).

The key 2200 is Downloads: Automatic prompting for file downloads 0=enable, 3 = disable.

AutomaticPromptingForFileDownloads

It seemed a reboot was necessary to pick up this change, after which all seemed better.

64 Bit Detection

22. May 2012 17:53

 

I’ve used this code on a few projects which needed to know if they were running on a 64 bit host.

 

  Private Shared Function Is64BitOs() As Boolean
        If IntPtr.Size = 8 Or (IntPtr.Size = 4 And Is32BitProcessOn64BitProcessor()) Then
            Return True
        Else
            Return False
        End If
    End Function

    Private Shared Function Is32BitProcessOn64BitProcessor() As Boolean
        Dim retVal As Boolean = False
        Try
            ' clear any exising error
            SetLastErrorEx(0, 0)
            If IsWow64Process(Process.GetCurrentProcess.Handle, retVal) Then
                Return retVal
            Else
                ' function call failed
                Throw New Exception(String.Format("IsWow64Process failed, lastError = {0}", Marshal.GetLastWin32Error))
            End If
        Catch ex As Exception
            Throw
        End Try
    End Function

    <DllImport("Kernel32.dll", SetLastError:=True, CallingConvention:=CallingConvention.Winapi)> _
    Private Shared Function IsWow64Process( _
                    ByVal hProcess As IntPtr, _
                    ByRef wow64Process As Boolean) As <MarshalAs(UnmanagedType.Bool)> Boolean

    End Function

    <DllImport("user32.dll")> _
    Private Shared Sub SetLastErrorEx(ByVal dwErrCode As UInteger, ByVal dwType As UInteger)
    End Sub

About the author

I'm a .NET developer, a husband and a father of three beautiful girls.

Month List