Archive

Posts Tagged ‘C#’

Performance tip – Caching expiry in web applications


Caching data that rarely change can give you a big performance boost especially if it takes time to fetch and/or calculate that data. In .NET 4.0, Microsoft introduced the .NET Memory Cache which is a thread safe cache that can be used Windows and Web applications. For more information about the MemoryCache class you can visit https://msdn.microsoft.com/en-us/library/system.runtime.caching.memorycache(v=vs.110).aspx

While I was doing a load test for web application for one of my clients, I noticed that the Queued Requests performance counter goes up every five minutes. By using a code profiler, it showed that there were many calls to refresh some of the cached data. Taking a closer look at the code below, if user 1 executing line (value = service.GetStreets();) while the other users are checking if value is cached, there is a potential of thousands of requests to fetch the same data especially if that data is frequently used.

We were using a CacheWrapper that applies a cache policy based on the cache name. With the CacheWrapper we can write the code to cache the Street Streets as follows:


public List<Street> GetStreets()
{

var value = CacheWrapper.Get(CacheNames.Streets) as List<Street>;

if (value == null)
{

    value = service.GetStreet();
    CacheWrapper.Set(CacheNames.Streets, value);

}

return value;

}

My first approach was to use a lock and double check the value


bool StreetsDataInitialized = false;
Object StreetsLock = new Object();

public List<Street> GetStreets()
{

var value = CacheWrapper.Get(CacheNames.Streets) as List<Street>;

if (value == null)
{
StreetsDataInitialized = false;

lock (StreetsLock)
 {
 if (StreetsDataInitialized)
 {
    return CacheWrapper.Get(CacheNames.Streets) as List<Street>;
 }

 value = service.GetStreets();
 CacheWrapper.Set(CacheNames.Streets, value);
 StreetsDataInitialized = true;

}

}

return value;

}

But there were many values that need to be cached and refreshed and I didn’t want to create two variables per cached value. I came up with a more generic way to achieve my goal. I started with the CacheLock Class

 public class CacheLock
  {
     public bool Initialized { get; set; }
     public object LockObject = new object();

 }

I used the ConcurrentDictionary to store the locks. I also created a generic GetOrSetCacheValue function which gets or creates a CacheLock for each cached data and invoke “function” if the data is not cached.


Public class CacheableLookupProvider
{
private static ConcurrentDictionary<string, CacheLock> LockDictionary = new ConcurrentDictionary<string, CacheLock>();
private readonly IStreetsService service;

Public CacheableStreetsProvider(IStreetsService service)
{
    this.service = service;
}

 private T GetOrSetCachedValue<T>(string cacheName, Func<T> function) where T : class
 {
    var value = CacheWrapper.Get(cacheName) as T;
    if (value == null)
     {
       var lockObject = LockDictionary.GetOrAdd(cacheName, new CacheLock());
       lockObject.Initialized = false;
      
      lock (lockObject.LockObject)
       {
         if (lockObject.Initialized)
         {
           return CacheWrapper.Get(cacheName) as T;
         }
         value = function();
         CacheWrapper.Set(cacheName, value);
         lockObject.Initialized = true;
       }
    }
    return value;
 }

 public List<Street> GetStreets ()
 {
    return GetOrSetCachedValue(CacheNames.Streets, () => service.GetStreets());
 }

 public List<Province> GetProvinces ()
 {
   return GetOrSetCachedValue(CacheNames.Provinces, () => service. GetProvinces());
 }

}

Categories: asp.net Tags: , , ,

Read Authorization section from Web.config


In my current project, I had to read the find the Windows group for the ESB portal which can be found in the authorization section of the web.config for the ESB portal. I used the following code to read it:

var config = System.Web.Configuration.WebConfigurationManager.OpenWebConfiguration(“/Bam”, “Default web Site”);
var section = config.GetSection(“system.web/authorization”) as AuthorizationSection;

if (section == null)
{
    return string.Empty;
}

foreach (AuthorizationRule rule in section.Rules)
{
     if (rule.Action.ToString().ToLower() == “allow” && rule.Roles.Count > 0)
     {
        foreach (var item in rule.Roles)
        {
            if (item != “*”)
            {
                return rule.Roles[0];
            }
        }
    }
}
return string.Empty;

[/soucecode]

Categories: .NET, asp.net, C#, Tips Tags: , ,

TFS2010: Retrieve Associated Workitems to Changesets TFS API


How to Retrieve Workitems Associated to Changesets in TFS using C# and VB.net

You need to add the following references

Microsoft.TeamFoundation.Client.dll

Microsoft.TeamFoundation.VersionControl.Client.dll

Microsoft.TeamFoundation.WorkItemTracking.Client.dll

They are located at “C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\ReferenceAssemblies\v2.0\” on my Windows 7 instance


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.TeamFoundation.Client;
using Microsoft.TeamFoundation.VersionControl.Client;
using Microsoft.TeamFoundation.WorkItemTracking.Client;

namespace ConsoleApplication2
{
    class Program
    {
        static void Main(string[] args)
        {
            var changeset = GetChangeset(new Uri("http://win7-pc:8080/tfs/defaultcollection"), 21);
            foreach (var w in changeset.WorkItems)
            {
                Console.WriteLine("WorkItemId:" + w.Id);
                Console.WriteLine("WorkItemTitle:" + w.Title);

            }
            Console.ReadLine();
        }

        private static Changeset GetChangeset(Uri serverUri, int changesetId)
        {
            var tfs = new TfsTeamProjectCollection(serverUri);
            var svc = tfs.GetService<VersionControlServer>();
            var changeset = svc.GetChangeset(changesetId);

            return changeset;
        }
    }
}

 

Imports Microsoft.TeamFoundation.VersionControl.Client
Imports Microsoft.TeamFoundation.Client
Imports Microsoft.TeamFoundation.WorkItemTracking.Client

Module Module1

    Sub Main()

        Dim changeset As Changeset = GetChangeset(New Uri("http://win7-pc:8080/tfs/defaultcollection"), 21)
        For Each w As WorkItem In changeset.WorkItems
            Console.WriteLine("WorkItemId:" & w.Id)
            Console.WriteLine("WorkItemTitle:" & w.Title)
        Next

        Console.ReadLine()

    End Sub

    Function GetChangeset(ByVal serverUri As Uri, ByVal changesetId As Integer) As Changeset
        Dim tfs As TfsTeamProjectCollection = New TfsTeamProjectCollection(serverUri)
        Dim svc = tfs.GetService(Of VersionControlServer)()
        Dim changeset As Changeset = svc.GetChangeset(changesetId)

        Return changeset
    End Function
End Module

Categories: .NET, C#, TFS, TFS2010, VB Tags: , , ,

WCF Data Service Exception: The LoadAsync method cannot be called when the DataServiceCollection is not a child collection of a related entity


In code you most likely called the no argument LoadAsync() method. Make sure you call pass the correcgt URI to the LoadAsync method. For example: if you service is located at http://localhost:1033/Services/PersonInfoService.svc/People

Make sure you pass the service URI without /People to the service context and pass /People to to the LoadAsync method

var people = new PersonEntities(new Uri("http://localhost:1033/Services/PersonInfoService.svc/"));
var Items = new DataServiceCollection<Person>(people);
//Pass the collection path to the LoadAsync method
Items.LoadAsync(new Uri("/People", UriKind.Relative));
Categories: .NET, C#, OData, Services, WCF Tags: , , ,

Use Red Gate SmartAssembly in Automated Team Build to Obfuscate Assemblies


This post is in response to a question asked in the TFS Automated Build Forum: http://social.msdn.microsoft.com/Forums/en-US/tfsgeneral/thread/44de4e0a-fcc0-4874-a4af-804dc458f43f/#b0c4c0a3-758a-4204-ac4b-d4e1e93e2d75.

Smart Assembly is a product to obfuscate .NET assemblies and automated error reporting. For more information about the tool, you can visit http://www.red-gate.com/products/dotnet-development/smartassembly/

To answer the question in the MSDN forum, I downloaded and installed the trial version Smart Assembly from Red Gate’s website. There wasn’t anything tricky while installing the product and it was straight forward.

I had to create a smart assembly project (.saproj) file which is an xml file that contains all the features that need to be enabled and their configuration. Smart Assembly comes with its configurator which makes it really easy to configure the features to be used. The following is a screen shot of the configurator

Follow these steps to create a project

  • Click New Project
  • Click Browse Assembly button
  • Select the file to be obfuscated, you want to select the dll or exe file located in the bin\release folder

  • Click Set Destination button, the configurator doesn’t allow you to select the same destination file as the input one using the same folder (i.e. over write the input one)

  • I have set the destination to be bin\SmartAssembly\SmartAssemblyPOC.exe
  • Notice the toolbar, clicking on toolbar buttons auto scrolls to the respective section

  • Check the assembly that you want to obfuscate
  • Click Save project on the left list
  • Save the saproj at the same directory where the project is saved. You can choose other location if you want to
  • Test your project by clicking Build on the left

Usually we don’t have one project in a solution. Therefore it is not practical to open the smart assembly tool for every project and build it manually. Luckily, we can integrate building the smart assembly project while building the project using MSBuild.

I basically followed the instruction in this link;

  • Right click on your project
  • Unload the project
  • Find the following line if you have a vb project

<Import Project=$(MSBuildToolsPath)\Microsoft.VisualBasic.targets />

  • Or this line if you are using C#

<Import Project=$(MSBuildToolsPath)\Microsoft.CSharp.targets />

  • Below the above line add the Smart Assembly targets

<UsingTask TaskName=SmartAssembly.MSBuild.Tasks.Build
AssemblyName=SmartAssembly.MSBuild.Tasks, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7f465a1c156d4d57 />

<Target Name=AfterBuild
Condition= ‘$(Configuration)’ == ‘Release’ >
 <SmartAssembly.MSBuild.Tasks.Build ProjectFile=SmartAssemblyPOC.saproj
input=$(OutDir)SmartAssemblyPOC.exe

output=$(OutDir)SmartAssemblyPOC.exe

OverwriteAssembly=true

MarkAsReleased=true/>
</Target> 

  • Save the project
  • Load the project from solution explorer
  • I will quickly explain what the above lines mean. The UsingTask element maps the AssemblyName to the TaskName. Version is the version number of the SmartAssembly. If you are using version 5, change the version number to 5.0.0.0. AfterBuild target is executed after the build is complete to obfuscate the smartassemblyPOC.exe in the release folder and then override it on the same folder. The $(OutDir) will be replaced by MSBuild with output folder of your assembly. The input and output in the MSBuild task overrides the input and output in the saproj
  • Build the project in Visual studio to make sure it compiles and the assembly gets obfuscated
  • It is not necessary to include the saproj file in the project as long as it is checked in. To include the saproj in the project:

  • Check in your changes
  • You need the SmartAssembly executable to be installed on your build machine otherwise Team Build won’t be able to find the SmartAssembly Tasks
  • After the Team build is done, view the log file
  • Notice the execution of the SmartAssembly task

Extension methods in .NET


In many occasions a developer wants to extend classes, but cannot as those classes were either Sealed (Not Inheritable) or it would require considerable time with refactoring existing code to use the inherited classes. In other occasions, a developer may want to have a default implementation for an interface method without repeating the same code in the classes that implement the interface. Both of those scenarios weren’t possible without the Extension Methods feature.

In this post, I will explain how to implement Extension Methods in C# and VB.NET and the pros and cons of using them.

Life before the era of extension methods

Within this section, I will be referring to the following code snippets:

Shape class:


namespace ODNC_Shapes
{
    public abstract class Shape
    {
    }

}

IParallelogram and IEqualSides Interfaces:


namespace ODNC_Shapes

{

    public interface IParallelogram
    {
        
        double Height{ get; set; }
        double Width{ get; set; }
        double Area();
    }
public interface IEqualSides: IParallelogram
    {
    }
}

Rectangle class:


namespace ODNC_Shapes

{
    public class Rectangle : Shape, IParallelogram
    {
        public double Height { get; set; }
        public double Width { get; set; }

        public double Area()
        {
            return Height * Width;
        }
    }
}

Square class:

namespace ODNC_Shapes
{
    public sealed class Square : Rectangle, IEqualSides
    {
    }
}

Rhombus class:

namespace ODNC_Shapes
{
    public class Rhombus:Shape,IEqualSides
    {

        public double Height { get; set; }

        public double Width { get; set; }

        public double Area()
        {
            return Height * Width;
        }
    }
}

Triangle class:


namespace ODNC_Shapes

{

    public sealed class Triangle : Shape

    {

        public double Base { get; set; }

        public double Height { get; set; }

    }

}

The following is the class diagram for the above classes

The above may not be a practical example, but it is good enough to explain the problem we have. Let’s assume that we don’t have the source code or we can’t modify the code for any other reason. And we want to add a function to calculate the area to the Triangle class. We notice that the Triangle class is a sealed class and can’t be inherited (i.e. extended). As a work around, we have to do the following:

  1. Create a static method that accepts a triangle object as a parameter and returns a double type
  2. Write the code to calculate the area in that function
  3. Call function from your code

The following code snippet illustrates the above steps:

using System;
using ODNC_Shapes;

namespace ODNC_ConsoleApplication
{
    public class ShapesHelper
    {
        public static double CalculateArea(Triangle triangle)
        {
            if (triangle == null)
                throw new NullReferenceException("Triangle object is null.");

            return 0.5*(triangle.Base + triangle.Height);
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            Triangle triangle = new Triangle { Base = 5, Height = 10 };
            double area = ShapesHelper.CalculateArea(triangle);
            Console.WriteLine(String.Format("Area: {0}", area));
            Console.ReadKey();
        }
    }
}

 

What are extension methods

 MSDN defines extension methods as

“Extension methods enable you to “add” methods to existing types without creating a new derived type, recompiling, or otherwise modifying the original type”

“Extension methods are a special kind of static methods, but they are called as if they were instance methods on the extended type”

How to Create Extension Methods

the following are the steps to create extension methods for the classes that implement IEqualSides interface

  1. Create new class library project, name it ShapeExtensions
  2. Add new class, call it IEqualSidesExtensions
  3. Make it a static class
  4. Create a static function, name it Perimeter with the following signature and code
  5. 
    namespace ShapesExtensions
    {
        public static class IEqualSidesExtensions
        {
            public static double Perimeter(this IEqualSides iEqualSide)
            {
                if (IEqualSide == null)
                {
                    throw new NullReferenceException();
                }
    
                return 4 * iEqualSide.Height;
            }
        }
    }
    
    Imports System.Runtime.CompilerServices
    
    Public Module IEqualSides
        <Extension()>
        Public Function Perimeter(ByVal iEqualSides As ODNC_Shapes.IEqualSides) As Double
    
            If iEqualSides Is Nothing Then
                'Do something
            End If
    
            Return 4 * iEqualSides.Width
    
        End Function
    End Module
    

    Notice the signature of the above function. As wiered as it looks, but that is the syntax of an extension method in C#. You need to have “this” keyword, type of the class you are writing the extension for and a parameter. In VB, you need to create a Module, declare the method with a paremeter of type IEqualSides, and decorate the function with Extension attribute.

  6. Build the project
  7. Add a reference to this project to the project where you want to use this extension method
  8. Add a using statement for that namespace
  9. Create a new instance of square
  10. Notice that you will find that Perimeter function was detected by intellisense, as if it were an instance method. You don’t need to pass it any parameters in this case. You will get the same result if you create a new instance of Rhombus

In the above example we added an extension method for all types that implement the IEqualSides interface. We created the extension method on a separate project to reuse the method on multiple projects. We could have added the extension method on a the same project where we want to use it.

Pro’s & Con’s

Extension methods are special type of static methods. When .NET compiler find them, it binds them to the instances of that class type. In the above example, we could have called the Perimeter method with the following syntax:

double perimeter = IEqualSidesExtensions.Perimeter(square);

Although it was advertised that extension methods extends or add new functionality to sealed classes and classes we don’t own, it actually doesn’t do so. Extension methods are still static methods but we get better readability and intellisense support when using them.

To summarize the advantages of using extension methods, they:

  1. make your code more readable
  2. give you intellisense support
  3. can be defined for interfaces, classes and abstract classes to have default behaviour
  4. adhere to the encapsolution rule of OOP; extension methods can only access public properties and methods for that type

Let’s now jump into some disadvantages for using extension methods

  1. Maintainability: imagine every developer write his own extension method library. Developers in a team need to make sure that their extension methods don’t have the same name. The maintainablility issue still exist when using static methods in helper classes
  2. No compiler error when methods are declared in classes. When the same method is declared in the class (e.g. in the Square class), the compiler doesn’t warn you that the function is already declared as an extension method. In this case the compiler binds the caller to the method that is declared in the class. For example, if we declare a Perimeter function in the Square class, that function will be executed instead of the one that was declared as an extension method
  3. Extension methods are not virtual (overridable) methods. For instance if we add square instances to a list <IEqualSides> (i.e. list(of IEqualSides) or you cast a square object to IEqualSides then execute the Perimeter function, the extension method is called not the one in the square class!
  4. You need to make sure that you check for null exception in your extension method. One may think that he is calling an instance method when calling SquareInstance.Perimeter(). Remember that extension methods are still static methods.
  5. namespace ShapesExtensions
    {
        public static class IEqualSidesExtensions
        {
            public static double Perimeter(this IEqualSides iEqualSide)
            {
                if (iEqualSide == null) // <-----
                {
                    //do something   
                }
    
                return 4 * iEqualSide.Height;
            }
        }
    }
    
  6. Confusing syntax. Many will get intimidated when they see the syntax of an extension method for the first time
  7. Inconsistent syntax between C# and VB. I don’t like the inconsistency between C# and VB

Conclusion

  1. Neat feature to “extend” class
  2. Extension methods are not instance methods
  3. An extension method with the same name and signature as an interface or class method will never be called
  4. Could be maintenance chaos
  5. Watch for Null Exceptions
Categories: .NET, C#, VB Tags: , , , ,