C# Constructor Should not Call Virtual Method

Instantiating an object calls obviously the controller of the class. In the case that the class inherit from a second class, the base constructor is called before the code inside the derived class. This can be shown very easily by printing to the console every times the constructor is called.

class Program
{
    static void Main(string[] args)
    {
        var classA = new ClassA();
        Console.ReadLine();
    }
}

public class ClassA:ClassB
{
    public ClassA()
    {
        Console.WriteLine("ClassA Constructor");
    }
}
public class ClassB
{
    public ClassB()
    {
        Console.WriteLine("ClassB Constructor");
    }
}

ConstructorOrderCalls

Having a method virtual allow the derived class to override the method. If the base class call the method, this one call, if overrided, call the one in the derived class. This mean that if you are instantiating value in the derived class that this one will not have the data instantiated yet. This can produce unexpected error like having null reference or working with a set of data that is not initialized with the desired value. The problem is that in the life time of the class, this one could be inherited which create new unexpected scenarios of where the virtual method is defined.

We can transform the previous code into this scenario. For example, let’s create a new virtual method where we return a string. In the derived class, we will return the name of the current process. In the base class, we return a simple string. The derived class must instantiated the Process object to get information about the current process. This has been instantiated in the constructor. Since it will be called after that the base constructor is done with its initialization and since the base constructor call the virtual method, this one will crash. The error occurs because the base class call the method that is overrided. The override is executed. It uses a variable that is not yet instanciated.

public class ClassA:ClassB
{
    private Process currentProcess;
    public ClassA()
    {
        Console.WriteLine("ClassA Constructor");
        currentProcess = Process.GetCurrentProcess();
    }

    public override string TestMethod()
    {
        return currentProcess.ProcessName;
    }
}
public class ClassB
{
    public ClassB()
    {
        Console.WriteLine("ClassB Constructor");
        TestMethod();
    }

    public virtual string TestMethod()
    {
        return "Test";
    }
}

The result is that the TestMethod() from the base class call the TestMethod() of the derived class and crash at the currentProcess line.

CallingVirtualMethodInConstructorError

A simple way to solve this issue is to seal the class, but on the other hand, limit the possibility of expending your class and force you to not have virtual method on this sealed class. Or, you can limit the calls of virtual method inside constructor.

VisualStudio.com Build Problem With System.Object is defined in an assembly that is not referenced

Visual Studio 2013 build correctly your Asp.Net MVC under .Net Framework 4.5.2 but when you commit to Visual Studio TFS online the Build Server gives you an error about System.Object. The error that can be something about System.Object that is not defined in an assembled.

Here is the full exception.

Entities\Trading\Portefolio.cs (41): The type ‘System.Object’ is defined in an assembly that is not referenced. You must add a reference to assembly ‘System.Runtime, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a’.

This is because Visual Studio on your computer knows to get them by going into a system folders. For example, the folder C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\Facades has a lot of assembly that Visual Studio known on your computer .

To fix this problem you need to open your Web.Config file and add under System.Web a compilation section.

  <system.web>
    <compilation debug="true" targetFramework="4.5.2">
      <assemblies>
        <add assembly="System.Runtime, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
      </assemblies>
    </compilation>
    <httpRuntime targetFramework="4.5.2"/>
  </system.web>

An important notion is that the httpRuntime target framework must be the same as the one defined in the compilation. The last thing that might be required is to force msbuild to use the targetframework you want. To do so, open Visual Studio Online or edit within Visual Studio the Build Definition to use the framework 4.5.2 (or the one defined in your web.config). You have to set the framework to the same as the web.config. If you already have argument after /p you just need to append the targetframeworkversion with the framework version desired.

MsBuildTargetVersion

Finally, if you still have problem building with Visual Studio, at the time I am writing this article, the Visual Studio Online team have confirming me that they does not support the latest framework of .Net. This should be solve in few months.

Modifying TFS Bug states for a specify collection

If you want to modify workflow state in TFS for a specific collection you must use a command line tool name witadmin. This tool is located in the bin folder of Visual Studio.

%programfiles(x86)%\Microsoft Visual Studio 12.0\Common7\IDE

Here is an example for a collection name TEST. The first command named listwith give you the list of wit type.

witadmin listwitd /collection:http://yourtfsserver:8080/tfs/yourpath /p:TEST

listwith

This is interesting because if you want to modify the state for the Bug than you have the confirmation with witadmin and listwitd that you will have all type that we can edit, like Bug.

If you want to modify the state you need to export the definition into a XML file. You can apply your modification and then import it into TFS. It is a good practice to keep a version not altered before modifying the wit. In the case the importation goes wrong, you will be able to get it back to its previous state.

//Get the definition for BUG
witadmin exportwitd /collection:http://yourtfsserver:8080/tfs/yourpath /p:TEST /n:BUG /f:"C:\Code\FileName.xml"
//After your changes, you import back
witadmin importwitd /collection:http://yourtfsserver:8080/tfs/yourpath /p:TEST /f:"C:\Code\FileName.xml"

The file that you get from TFS allow you to specify states and transition between them. In the example above, we specify with the switch /n the type of TFS item we want to edit. The list of possible values come from listwitd. It is interesting to note that if you have already used some state that those one will continue to exist in TFS until it goes back to a state defined.

<WORKFLOW>
      <STATES>
        <STATE value="Done">
          <FIELDS>
            <FIELD refname="Microsoft.VSTS.Scheduling.Effort">
              <READONLY />
            </FIELD>
          </FIELDS>
        </STATE>
        <STATE value="New (1/4)" />
        <STATE value="Resolved (2/4)" />
        <STATE value="Deployed (3/4)" />
        <STATE value="Closed (4/4)" />
      </STATES>
      <TRANSITIONS>
        <TRANSITION from="" to="New (1/4)">
          <REASONS>
            <DEFAULTREASON value="Nouveau bug" />
          </REASONS>
          <FIELDS>
            <FIELD refname="Microsoft.VSTS.Common.BacklogPriority">
              <DEFAULT from="value" value="1000" />
            </FIELD>
          </FIELDS>
        </TRANSITION>
        <TRANSITION from="New (1/4)" to="Resolved (2/4)">
          <REASONS>
            <DEFAULTREASON value="Solve" />
          </REASONS>
        </TRANSITION>
        <TRANSITION from="Resolved (2/4)" to="Deployed (3/4)">
          <REASONS>
            <DEFAULTREASON value="Need to be tested" />
          </REASONS>
        </TRANSITION>
        <TRANSITION from="Deployed (3/4)" to="Closed (4/4)">
          <REASONS>
            <DEFAULTREASON value="Fixed" />
          </REASONS>
        </TRANSITION>
		<TRANSITION from="Deployed (3/4)" to="New (1/4)">
          <REASONS>
            <DEFAULTREASON value="Bug still present" />
          </REASONS>
        </TRANSITION>
        <TRANSITION from="New (1/4)" to="Closed (4/4)">
          <REASONS>
            <DEFAULTREASON value="Not a real bug" />
          </REASONS>
        </TRANSITION>
      </TRANSITIONS>
    </WORKFLOW>

This is is. After importing your modification into TFS your change will be reflected right after the command line is done.

IIS No Sleep (idle) and AutoStart with Values

It is important to have not only a good code but to have this one into a hosting environment that will make it looks good. One negative point that we hear with IIS is that when the application pool sleep, the user that do a query have a penalty of time on its first query. This can lead to several second of waiting. It is interesting to note that since at least 5 years that we can have IIS to auto start. It is also interesting to note that we can also make IIS not to become idle.

Changing IIS Idle Time

The first step to improve IIS performance is to remove the time out. This can be done by opening IIS, open the Application Pool you want to change the setting and to open the Advanced Setting Window. The window has a Process Model section where you will find Idle Time-out (minutes) setting. You can set this property to 0. By default, the Application Pool also recycle every few minutes. You can set it to 0 to have this one not recycle. This will cause a higher availability of IIS during the day where most client are. If your application have low period, let say that you are building for an internal website for a company, you can set a absolute time to recycle. This can be set in the same screen as before, the Advanced Setting of the Application Pool, by changing the Specific Times. For example, we can set to recycle the pool at 1 am every day.

AdvancedSettingApplicationPoolIISNoSleep

Auto Start

The auto start functionality is something that allow you to do an action when IIS start your application pool. For example, you could load in your caching system information from your database. You can also do some code that verify the availability of external webservice, etc. This require some manual editing of file on the server where reside your IIS. The file that needs to be edited is named applicationHost.config and it is located in the system folder : c:\windows\system32\inetsrv\config\.

The first section that you need to edit is the one that has your application pool name. You must ensure that you have autoStart = true and the startmode to alwaysrunning.

<add name="YourAppPoolName" 
     autoStart="true" 
     startMode="AlwaysRunning" 
     managedRuntimeVersion="v4.0">
     <processModel 
           identityType="SpecificUser" 
           userName="DefaultAppUserName"  
           idleTimeout="00:00:00" />
</add>

In the same file, the second section to find is the application path. You can find this section by searching your application name. You must have serviceAutoStartEnabled=true and to set a serviceAutoStartProvider to an unique name that we will define soon.

<application path="/YourApplicationPath" 
             applicationPool="YourAppPoolName" 
             serviceAutoStartEnabled="true" 
             serviceAutoStartProvider="YourProvider" >
             <virtualDirectory path="/" 
                               physicalPath="C:\inetpub\wwwroot\YourApplicationPath" />
 </application>

The provider name we just set needs to be defined. This can be done by adding a new section (if this one is not yet there) in the applicationHost.config file (same file that we are currently modifing the XML) under the section serviceAutoStartProviders.

<serviceAutoStartProviders>
 	    <add name="YourProvider" 
                 type="YourProvider, Full.NameSpace.To.YourProvider, version=1.0.0.0, Culture=neutral" />
</serviceAutoStartProviders>

IIS will get the DLL from your application bin folder and start running your custom code for your application when the application pool boot.

The last part is to code the custom code of your provider. This can be done by implementing a specific interface. This interface has a PreLoad method that is executed by IIS. The interface that you must implement is named IProcessHostPreloadClient.

public class YourProvider : IProcessHostPreloadClient
{
        public void Preload(string[] parameters)
        {
            
        }
}

Do not forget that this feature is available only for IIS 7.5 and above. Also, do not forget that you may have to do some additional code if you want to use your repository with your IoC container. If you are using the Http Cache that Asp.Net provides, you need to have the namespace added to your project that has the custom provider.

Asp.Net MVC EditorTemplate and DisplayTemplate with HtmlAttributes On Custom Template

The EditorTemplate and the DisplayTemplate can be used with the HtmlHelper EditorFor and DisplayFor. It is also possible to pass in a second parameter custom html attributes. This is very interesting if you need to add style class.

@Html.EditorFor(d => d.PriceLimit
               , new {htmlAttributes = new { @class = "col-md-8 order-price-money-limit" }})

The example above call the EditorFor on the PriceLimit property. It has in its second parameter an anonymous object that set htmlAttibutes. This one is also an anonymous object that set two classes. One class is for BootStrap and the second is a custom one.

If you have defined that the PriceLimit must use a custom home made template, than you may want to gather this information and use it on the html element you desire.

For example, this is the custom editor template:

<div ?????????>
    @Html.EditorFor(viewModel => viewModel.Current.Value)
    @Html.HiddenFor(viewModel => viewModel.Current.Currency.Id)
</div>

As you can see, the first line would like to benefit of the html attributes passed by the EditorFor.

The task would have been easy if we only wanted to pass the html attribute to a TextBoxFor, or any existing defined Html helper because you could simply set the viewdata back to the second parameter. However, if you are in the scenario that you want to use the html attributes for any html element, than some code must be done. Also, we need to think about the possibility that the custom editor template (or display template) may want to have html attribute by default and just be enhanced by the html attributes passed by the Html Helper.

<div class="constant-class-always-there ????" ?????????>
    @Html.EditorFor(viewModel => viewModel.Current.Value)
    @Html.HiddenFor(viewModel => viewModel.Current.Currency.Id)
</div>

The first task is to handle the case that we may want to have default attribute. The code that is following this paragraph is set at the top of the Editor Template. In this example, we want to be sure that the class “input-group” is set. Whatever what is passed on the Html Helper EditorFor, we want to have this class set.

@{
    object htmlAttributes = null;
    if (Html.ViewData.ContainsKey("htmlAttributes"))
    {
        htmlAttributes = Html.Custom().RenderHtmlAttributes(ViewData["htmlAttributes"], new { @class = "input-group" });
    }
    else
    {
        htmlAttributes = Html.Custom().RenderHtmlAttributes(new{@class="input-group"});
    }
}

The IF check if the EditorFor html helper contains any html attributes, if it is the case, than it add it to the EditorFor html attributes, otherwise, it just set it without taking care of the view data passed by the html helper. Something may have catch your attention : the RenderHtmlAttributes method. This is a custom html helper that takes one or multiple object and create a MvcHtmlString to be used to your Razor code. The end result would look like this:

@{
    object htmlAttributes = null;
    if (Html.ViewData.ContainsKey("htmlAttributes"))
    {
        htmlAttributes = Html.Custom().RenderHtmlAttributes(ViewData["htmlAttributes"], new { @class = "input-group" });
    }
    else
    {
        htmlAttributes =  Html.Custom().RenderHtmlAttributes(new{@class="input-group"});
    }
}
<div @htmlAttributes>
    @Html.EditorFor(viewModel => viewModel.Current.Value)
    @Html.HiddenFor(viewModel => viewModel.Current.Currency.Id)
</div>

The RenderHtmlAttributes loops all html attributes object and extend each of them to create a final RouteValueDictionary. Finally, it creates a string.

/// <summary>
/// Render one or many html attribute together
/// </summary>
/// <param name="htmlAttributes"></param>
/// <returns></returns>
public MvcHtmlString RenderHtmlAttributes(params object[] htmlAttributes)
{
	var finalRouteValue = new RouteValueDictionary();
	foreach (var htmlAttribute in htmlAttributes)
	{
		var routeValue = new RouteValueDictionary(htmlAttribute);
		finalRouteValue = finalRouteValue.Extend(routeValue);
	}
	var htmlAttributesString = String.Join(" ", finalRouteValue.Keys.Select(key => String.Format("{0}=\"{1}\"", key, this.htmlHelper.Encode(finalRouteValue[key]))));
	return MvcHtmlString.Create(htmlAttributesString);
}

The heavy lift about handling if one html attribute object contains a key that has already been defined or not to handle the merge is done in the Extend method. For example, if two html attributes define the key “class” than we want to merge both value to have in the final result a single “class” key with both class value defined.

/// <summary>
/// The extend method takes values from the source and add them into the destination. You do not need to use the return value
/// because the destination object will already have the element of the source.
/// </summary>
/// <param name="destination"></param>
/// <param name="source"></param>
/// <returns></returns>
public static RouteValueDictionary Extend(this RouteValueDictionary destination, IEnumerable<KeyValuePair<string, object>> source)
{
	foreach (var srcElement in source.ToList())
	{
		if (destination.ContainsKey(srcElement.Key))
		{
			destination[srcElement.Key] += " " + srcElement.Value;
		}
		else
		{
			destination[srcElement.Key] = srcElement.Value;    
		}
		
	}
	return destination;
}

Here is two unit tests. The first one has two different keys. The end result is that both keys are not merged together. The second test has two route value with the same key. Each of them with different values. The result is that both value are in the first object.

[TestClass]
public class RouteExtensionsTest
{
	[TestMethod]
	public void GivenTwoRouteValueDictionary_WhenBothDoesNotContainSameKey_ThenValueAreNotMerged()
	{
		// Arrange
		var valueObject1 = new RouteValueDictionary { { "key1", "value1" } };
		var valueObject2 = new RouteValueDictionary { { "key2", "value2" } };

		// Act
		valueObject1.Extend(valueObject2);

		// Assert
		Assert.AreEqual("value1", valueObject1["key1"].ToString());
	}

	[TestMethod]
	public void GivenTwoRouteValueDictionary_WhenBothContainSameKey_ThenValueAreMerged()
	{
		// Arrange
		var valueObject1 = new RouteValueDictionary {{"key1", "value1"}};
		var valueObject2 = new RouteValueDictionary {{"key1", "value2"}};

		// Act
		valueObject1.Extend(valueObject2);

		// Assert
		Assert.AreEqual("value1 value2", valueObject1["key1"].ToString());
	}
}

It requires some work to work with Editor Template and Display Template when you want to go beyond basic functionality. However, it is possible to extend everything with some Html Helper and Extension methods.