Showing posts with label C#. Show all posts
Showing posts with label C#. Show all posts

Monday, June 15, 2015

MVC6 SecretManager

I tried to install ASP.NET MVC6 Secret Manager package with DNVM  1.0.0-beta4. It failed with:
Unable to locate SecretManager >= 1.0.0-beta4-10173
There is an easy fix: you can remove the last part of the version identifier.

  1. Open project.json file
  2. Change version to 
 "dependencies": {
    "SecretManager": "1.0.0-beta4-*"
  },
Files to be changed:
Package path:%UserProfile%\.dnx\packages\SecretManager\1.0.0-beta4\app\project.json
Cache path:%UserProfile%\.dnx\bin\packages\SecretManager\1.0.0-beta4\app\project.json

Wednesday, June 10, 2015

RouteValueDictionary

I got an error recently when I enable DonutCache donutHole-based caching for a RenderAction:
Type 'System.String[]' with data contract name 'ArrayOfstring:http://schemas.microsoft.com/2003/10/Serialization/Arrays' is not expected. Consider using a DataContractResolver or add any types not known statically to the list of known types - for example, by using the KnownTypeAttribute attribute or by adding them to the list of known types passed to DataContractSerializer.
It seems RouteValueDictionary cannot manage IEnumerable or String[] as a parameter. The solution is simple, it's a well-known issue:
http://stackoverflow.com/questions/19960420/adding-array-of-complex-types-to-routevaluedictionary

So this is how you can use the extension method:
Html.RenderAction(
                             ActionName,
                             ControllerName,
                             new RouteValueDictionary(new 
                             {      usual properties here }));


Thursday, May 15, 2014

Partial apply in C#

Partial apply by Wikipedia:

In computer science, partial application (or partial function application) refers to the process of fixing a number of arguments to a function, producing another function of smaller arity. Given a function \scriptstyle f \colon (X \times Y \times Z) \to N , we might fix (or 'bind') the first argument, producing a function of type  \scriptstyle\text{partial}(f) \colon (Y \times Z) \to N . Evaluation of this function might be represented as f_{partial}(2, 3). Note that the result of partial function application in this case is a function that takes two arguments.

In short, that means you define (bind) some of the possible arguments and leave some to be filled in later (free).

Scala

def sum(a:Int, b:Int, c:Int):Int = a+b+c  //> sum: (a: Int, b: Int, c: Int)Int
sum(1,2,3)                                //> res11: Int = 6

def sum1 = sum(1, _:Int, _:Int)           //> sum1: => (Int, Int) => Int
sum1(2,3)                                 //> res12: Int = 6

def sum2 = sum(_:Int, 2, _:Int)           //> sum2: => (Int, Int) => Int
sum2(1,3)                                 //> res13: Int = 6

sum1 binds the first parameter but the other two parameters are free. As you can see from the result it gets translated to a lambda with two parameters.

sum2 binds the second parameter. The result is the same, a lambda with two parameters.

C#

C# has no built-in operator for applying a function, so we have to write the lambdas directly.

readonly Func sum = (x, y, z) => x + y + z;

[Fact]
public void Sum()
{
    var result = sum(1, 2, 3);

    Assert.Equal(6, result);
}

[Fact]
public void Sum_PartialApply_FirstParam()
{
    Func sum1 = (y, z) => sum(1, y, z);

    var result = sum1(2, 3);

    Assert.Equal(6, result);
}

[Fact]
public void Sum_PartialApply_SecondParam()
{
    Func sum2 = (x, z) => sum(x, 2, z);

    var result = sum2(1, 3);

    Assert.Equal(6, result);
}

Wednesday, May 14, 2014

Loan pattern in C#

There is a pattern is Scala called loan pattern. You open a resource, “loan” the resource to another function, and the loaner closes the resource.

Scala

This function expects a file a function. When it's called it creates the resource, executes the function and closes the resource.

def withPrintWriter(file: File, op: PrintWriter => Unit) {
  val writer = new PrintWriter(file)
  try {
    op(writer)
  } finally {
    writer.close()
  }
}

This is how it's called:

withPrintWriter(
  new File("date.txt"),
  writer => writer.println(new java.util.Date)
)

C#

Now I extended the definition with currying:

readonly Func, string>> openFile = 
    path => 
        handler =>
            {
                var reader = new StreamReader(path);
                try
                {
                    return handler(reader);
                }
                finally
                {
                    reader.Close();
                    Console.WriteLine("Stream closed");
                }
            };

Here are two examples on calling the function above:

readonly Func readAllLines = input => input.ReadToEnd();
readonly Func readSingleLine = input => input.ReadLine();

[Fact]
public void LoanPattern_AllText()
{
    var result = openFile("TextFile1.txt")(readAllLines);
    Assert.Equal("This is the test content.\r\nThis is a second line.", result);
}

[Fact]
public void LoanPattern_ReadSingleLine()
{
    var result = openFile("TextFile1.txt")(readSingleLine);
    Assert.Equal("This is the test content.", result);
}

Result

Now the code calling the function (openFile) is much simpler and there is no need for error handling in the caller. Furthermore thanks to currying, even the resource name can be bound in the constructor, hiding the resource initialization as well.

Thursday, May 8, 2014

Currying in Scala and C#

Currying is an interesting and powerful functional programming concept. Interestingly currying can be used in C# as well.

The usual approach

Let's define a simple add function that sums two numbers in C#:

[Fact]
public void SimpleAdd_AsInlineFunction_WithLambda()
{
    Func<int, int, int> add = (x, y) => x + y;
    var result = add(5, 7);
    Assert.Equal(12, result);
}

The same in Scala:

def add(x:Int,y:Int) = x+y                      //> add: (x: Int, y: Int)Int
add(5,7)                                        //> res0: Int = 12
Or with lambda:
def add_lambda = (x:Int,y:Int) => x+y           //> add_lambda: => (Int, Int) => Int
add_lambda(5,7)                                 //> res1: Int = 12

Currying

Now Implement the same function in C#, but this time with currying:

[Fact]
public void CurryingAdd()
{
    Func<int, Func<int, int>> add = x => y => x + y;
    var result = add(5)(7);
    Assert.Equal(12, result);
}

In Scala:

def add_lambda_currying(x:Int) = (y:Int) => x+y //> add_lambda_currying: (x: Int)Int => Int
add_lambda_currying(5)(7)                       //> res2: Int = 12

With simplified Scala syntax:

def add_currying(x:Int)(y:Int): Int = x+y       //> add_currying: (x: Int)(y: Int)Int
add_currying(5)(7)                              //> res3: Int = 12

Partial apply

Now let’s suppose I want to bind the first parameter to a concrete value (bound) but I want to keep the second parameter unbounded (free).

This is the way in C#:

[Fact]
public void CurryingAdd_Add5()
{
    Func> add = x => y => x + y;
    var add5 = add(5);
    
    var result1 = add5(7);
    Assert.Equal(12, result1);

    var result2 = add5(122);
    Assert.Equal(127, result2);
}

The same idea in Scala:

def add5_lambda_currying = add_lambda_currying(5)  //> add5_lambda_currying: => Int => Int
add5_lambda_currying(7)                         //> res3: Int = 12

def add5_currying = add_currying(5) _           //> add5_currying: => Int => Int
add5_currying(7)                                //> res5: Int = 12

In case of the add5_currying example please notice the underscore (_) at the end of the expression. That means partial apply and indicates that I don’t want to bind the second parameter. There is no need for such indicator with lambda syntax.

Friday, February 7, 2014

Functional C# - insight by Python

Python has many powerful functions. I realized there are many similar functions available in .NET.

Enumerable.Aggregate
Function Description .NET
zip Pairs iterables element by element:

* x = [1, 2, 3]
* y = [4, 5, 6]
* zipped = zip(x, y)
* zipped
[(1, 4), (2, 5), (3, 6)]

Enumerable.Zip

int[] numbers = { 1, 2, 3, 4 };
string[] words = { "one", "two", "three" };

var numbersAndWords = 
    numbers.Zip(words, (first, second) => first + " " + second);

foreach (var item in numbersAndWords)
    Console.WriteLine(item);

// 1 one 
// 2 two 
// 3 three

reduce Apply function of two arguments cumulatively to the items of iterable, from left to right, so as to reduce the iterable to a single value. For example,
reduce(lambda x, y: x+y, [1, 2, 3, 4, 5])
calculates
((((1+2)+3)+4)+5)
.
Enumerable.Aggregate

string sentence = "the quick brown fox jumps over the lazy dog";

// Split the string into individual words. 
string[] words = sentence.Split(' ');

// Prepend each word to the beginning of the  
// new sentence to reverse the word order. 
string reversed = words.Aggregate((workingSentence, next) =>
                                                  next + " " + workingSentence);

// dog lazy the over jumps fox brown quick the 
filterConstruct a list from those elements of iterable for which function returns true.

filter(lambda x: x%2, range(10)) 
result: 1 3 5 7 9
Enumerable.Where
List fruits =
new List { "apple", "passionfruit", "banana", "mango", 
    "orange", "blueberry", "grape", "strawberry" };

IEnumerable query = fruits.Where(fruit => fruit.Length < 6);

/*
This code produces the following output:

apple
mango
grape
*/

Monday, November 11, 2013

Pragmatism

My background

I'm a .NET, mainly C# programmer. Nowadays I focus on web applications. I usually work on enterprise-grade applications.

I came across Python a year ago on a training session. I was shocked by the syntax but I felt the power of the language and the toolset.

Pragmatism

I think I need to define what is pragmatism for me in the context of software engineering: when a customer has a business problem, your responsibility as an engineer is to choose the proper tools to fulfil the real needs of this customer.

Pragmatic tools

A tool can be a language, a framework, a design or architectural pattern.

Business domain

The real need means a customer usually can't express the whole problem to the team (or even mislead the the team with half or missing information) so the developer (or analyst) needs to dig deep into the business problem and understand the domain before the actual coding gets started.

Pragmatic programming

The first thing is to understand the business domain. A developer has to constantly check the requirements against the customer's ideas and the business domain to make sure there is no misunderstanding. It also applies to the QA (tester) personnel as well. Only the joint work of the analysts, developers and QAs (regarding only the development team) can ensure the success of the implementation considering the business domain and real needs.

The pragmatic programmer does not stick to the favorite language (e.g. C#) she knows:
  • C# is a good choice for GUI, especially with WPF and Windows in mind. On the other hand Python can be a better choice for log analysis, mathematical modeling and statistical processing (considering NumPy, SciPy and Pandas). 
  • WCF (as an XML web service) is powerful for enterprise-grade service implementations but REST can be a better choice for thin APIs with mobile clients.
  • WCF is a powerful end-point provider but node.js can be a better choice if you have an AJAX-heavy web application with some kind of model-based JS framework. In case of node.js you don't need to transform your data from a static-typed language to a dynamic language. Less layers, less transformation, less technology and tooling. 
  • ASP.NET MVC is an easy-to-learn and thin layer for web application development. I like it, but I know Ruby on Rails or even Django (Python) can be as powerful or even more powerful for your particular task.
  • Entity Framework is powerful with its own limitations, but sometimes it worths going back to the basics with direct ADO.NET calls. Or does it? Consider Dapper, OrmLite and such.
  • Object-oriented programming is well-understood but functional elements can make the code more robust and easier to manage.
  • Defensive programming with guards is useful but what about code contracts (even the Microsoft implementation or in general)?
  • Scrum is good and has proved, but how can I adapt it to the current customer? Or shouldn't I choose Kanban? Or Scrumban? Do I need to integrate with an existing project management 'system'? Anyway, do I need to choose an agile methodology at all (yes, it should be prefered :) )?
There are always alternatives and the engineer's job should be choosing the right mix of these alternatives.

Wednesday, April 17, 2013

Unit testing a Powershell Commandlet

I chose to write Powershell commandlets in C#. I created a class library (DLL) project and inherited a class from Cmdlet base class. I created a snapin class derived from PSSnapIn to be able to install my commandlets from powershell.

Unit testing

Writing a unit test

[TestClass]
    public class UnitTest1
    {
        private static RunspaceConfiguration config;
        private static Runspace runspace;
        private static Pipeline pipe;
        private static Command command;

        [ClassInitialize]
        public static void TestFixtureSetup(TestContext context)
        {
            config = RunspaceConfiguration.Create();

            PSSnapInException warning;
            config.AddPSSnapIn("SnapinName", out warning);

            runspace = RunspaceFactory.CreateRunspace(config);
            runspace.Open();
        }

        [ClassCleanup]
        public static void TestFixtureTeardown()
        {
            runspace.Close();
        }

        [TestInitialize]
        public void Setup()
        {
            pipe = runspace.CreatePipeline();
            command = new Command("CommandName");
            pipe.Commands.Add(command);
        }

        [TestMethod]
        public void TestMethod1()
        {
            command.Parameters.Add(new CommandParameter("ParameterName", "Value"));

            var psObject = pipe.Invoke();
        }
    }

Snapin couldn't be found

I wrote a unit test against one of my commands but it couldn't find my snapin, I got the following exception:
System.Management.Automation.PSArgumentException: System.Management.Automation.PSArgumentException: The Windows PowerShell snap-in '...' is not installed on this computer..

I could use my snapin from Powershell command line.

Solution

Add the following lines as post-build events:
c:\Windows\Microsoft.NET\Framework64\v4.0.30319\InstallUtil.exe $(TargetPath)
c:\Windows\Microsoft.NET\Framework\v4.0.30319\InstallUtil.exe  $(TargetPath)

Both 32-bit and 64-bit installation will happen this way.

Cause

Visual Studio 2012 is a 32-bit process. I registered with 64-bit install util only. Now I register both versions.

Sunday, October 31, 2010

Simple Map Reduce Example in C#

This is an example of map-reduce implementation for IEnumerable. This code is not optimized. I think we shouldn’t create separate Task for each enumerated item. Probably partitioning the enumeration and dealing with bigger chunks of data would be much more efficient.

Browse source code: Google Code

MapReduce function for IEnumerable:

using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Collections;

namespace MapReduceCode
{
    public static class MapReduce
    {
        public static Task<TResult> ForEachParallel<TItem, TSubResult, TResult, TParam>(this IEnumerable items, Func<TItem, TParam, TSubResult> map, Func<TSubResult[], TResult> reduce, TParam param)
        {
            if (items == null) { throw new ArgumentNullException("items"); }
            if (map == null) { throw new ArgumentNullException("map"); }
            if (reduce == null) { throw new ArgumentNullException("reduce"); }

            return Task<TResult>.Factory.StartNew(() =>
            {
                List<Task<TSubResult>> tasks = new List<Task<TSubResult>>();

                foreach (TItem item in items)
                {
                    Task<TSubResult> t = Task<TSubResult>.Factory.StartNew(item2 =>
                        {
                            var mparam = (Tuple<TItem, TParam>)item2;
                            return map(mparam.Item1, mparam.Item2);
                        },
                        new Tuple<TItem, TParam>(item, param),
                        TaskCreationOptions.None | TaskCreationOptions.AttachedToParent);
                    tasks.Add(t);
                }

                List<TSubResult> results = new List<TSubResult>();
                foreach (Task<TSubResult> task in tasks)
                {
                    results.Add(task.Result);
                }

                return reduce(results.ToArray());
            });
        }
    }
}

Usage example:

using System;
using System.Collections;
using MapReduceCode;
using System.Threading;
using System.Threading.Tasks;

namespace MapReduce
{
    class Program
    {
        static void Main(string[] args)
        {
            var a = Generate().ForEachParallel<int, int, int, int>(
                (element, param)=> 
                {
                    var result = element * param;
                    Console.WriteLine("Map: {0}, {1}", result, Task.CurrentId);
                    Thread.Sleep(new Random(DateTime.Now.Millisecond).Next(500));
                    return result;
                }, 
                (subresult)=>
                {
                    var sum = 0;
                    foreach (var item in subresult)
                    {
                        sum += item;
                    }
                    Console.WriteLine("Reduce: {0}", sum);
                    return sum;
                }, 
                5);

            Console.WriteLine(a.Result);
            
        }

        static IEnumerable Generate()
        {
            for (int i = 0; i < 100; i++)
            {
                yield return i;
            }
        }
    }
}

Result:

Map: 0, 1
Map: 5, 2
Map: 10, 3
Map: 20, 4
Map: 15, 5
Map: 25, 6
Map: 30, 7
Map: 35, 8
Map: 40, 9
Map: 45, 10
Map: 50, 11
Map: 55, 12
Map: 60, 13
Map: 65, 14
Map: 70, 15
Map: 75, 16
Map: 80, 17
Map: 85, 18
Map: 90, 19
Map: 95, 20
Map: 100, 21
Map: 105, 22
Map: 110, 23
Map: 115, 24
Map: 120, 25
Map: 125, 26
Map: 130, 27
Map: 135, 28
Map: 140, 29
Map: 145, 30
Map: 150, 31
Map: 155, 32
Map: 160, 33
Map: 165, 34
Map: 170, 35
Map: 175, 36
Map: 180, 37
Map: 185, 38
Map: 190, 39
Map: 195, 40
Map: 200, 41
Map: 205, 42
Map: 210, 43
Map: 215, 44
Map: 225, 45
Map: 230, 47
Map: 220, 46
Map: 235, 48
Map: 245, 50
Map: 240, 49
Map: 250, 51
Map: 255, 52
Map: 260, 53
Map: 265, 54
Map: 275, 56
Map: 270, 55
Map: 285, 57
Map: 280, 58
Map: 290, 59
Map: 295, 60
Map: 300, 62
Map: 305, 61
Map: 310, 63
Map: 315, 64
Map: 320, 65
Map: 325, 66
Map: 330, 67
Map: 335, 68
Map: 340, 69
Map: 355, 72
Map: 350, 71
Map: 360, 73
Map: 365, 74
Map: 345, 70
Map: 370, 75
Map: 380, 77
Map: 375, 76
Map: 390, 79
Map: 395, 80
Map: 385, 78
Map: 400, 81
Map: 405, 82
Map: 415, 84
Map: 425, 86
Map: 410, 83

Map: 420, 85
Map: 430, 87
Map: 440, 89
Map: 435, 88
Map: 450, 90
Map: 445, 91
Map: 455, 92
Map: 460, 93
Map: 470, 95
Map: 480, 97
Map: 475, 96
Map: 485, 98
Map: 465, 94
Map: 490, 99
Map: 495, 100
Reduce: 24750
24750

Wednesday, May 19, 2010

CAL and AutoMapper

I’m using Composite Application Library (CAL) in a project. I decided to use AutoMapper as well. I put AutoMapper’s Mapper.CreateMap<source, dest>() calls into one of the Bootstrapper.cs methods. I got an InvalidOperationException in the ModuleCatalog’s InnerLoad() function.

Reason

AutoMapper creates an in-memory assembly and CAL tries to read all the assemblies’ Location property. This property raises an InvalidOperationException in case of in-memory assemblies.

Solution

Insert AutoMapper mappings right after the Bootstrapper.Run() call. In my case I call this in App.xaml.cs, so you can write the following:

protected override void OnStartup(StartupEventArgs e)
{
    base.OnStartup(e);

    // Run bootstrapper
    Bootstrapper bootstrapper = new Bootstrapper();
    bootstrapper.Run();

    // AutoMapper mappings
    Parallel.Invoke(CreateAutoMapperMappings);
}

/// <summary>
/// Creates the AutoMapper mappings.
/// </summary>
private static void CreateAutoMapperMappings()
{
    Mapper.CreateMap<Source, Dest>();
}

Sunday, May 2, 2010

Get WPF DataGrid row and cell

There are no simple built-in methods for accessing individual rows or columns in WPF DataGrid. The following code samples will provide simple methods for accessing these items.

First of all we need a helper function for selecting a visual child:

public static T GetVisualChild<T>(Visual parent) where T : Visual
{
    T child = default(T);
    int numVisuals = VisualTreeHelper.GetChildrenCount(parent);
    for (int i = 0; i < numVisuals; i++)
    {
        Visual v = (Visual)VisualTreeHelper.GetChild(parent, i);
        child = v as T;
        if (child == null)
        {
            child = GetVisualChild<T>(v);
        }
       if (child != null)
       {
           break;
       }
   }
       return child;
}

There is a simple method for getting the current (selected) row of the DataGrid:

public static DataGridRow GetSelectedRow(this DataGrid grid)
{
    return (DataGridRow)grid.ItemContainerGenerator.ContainerFromItem(grid.SelectedItem);
}

We can also get a row by its indices:

public static DataGridRow GetRow(this DataGrid grid, int index)
{
    DataGridRow row = (DataGridRow)grid.ItemContainerGenerator.ContainerFromIndex(index);
    if (row == null)
    {
        // May be virtualized, bring into view and try again.
        grid.UpdateLayout();
        grid.ScrollIntoView(grid.Items[index]);
        row = (DataGridRow)grid.ItemContainerGenerator.ContainerFromIndex(index);
    }
    return row;
}

Now we can get a cell of a DataGrid by an existing row:

public static DataGridCell GetCell(this DataGrid grid, DataGridRow row, int column)
{
    if (row != null)
    {
        DataGridCellsPresenter presenter = GetVisualChild<DataGridCellsPresenter>(row);

        if (presenter == null)
        {
            grid.ScrollIntoView(row, grid.Columns[column]);
            presenter = GetVisualChild<DataGridCellsPresenter>(row);
        }

        DataGridCell cell = (DataGridCell)presenter.ItemContainerGenerator.ContainerFromIndex(column);
        return cell;
    }
    return null;
}

Or we can simply select a row by its indices:

public static DataGridCell GetCell(this DataGrid grid, int row, int column)
{
    DataGridRow rowContainer = grid.GetRow(row);
    return grid.GetCell(rowContainer, column);
}

The functions above are extension methods. Their use is simple:

var selectedRow = grid.GetSelectedRow();
var columnCell = grid.GetCell(selectedRow, 0);

View source on Google Code (unformatted selection possible)

Saturday, April 17, 2010

Mixed mode assemblies on .NET 4.0

Mixed mode assembly is built against version 'v2.0.50727' of the runtime and cannot be loaded in the 4.0 runtime without additional configuration information.

I got this message when I tried to start a project migrated from .NET 3.5 to .NET 4.0. I case of migration, migration wizard inserts a <startup></startup> tag into the app.config file.

Solution: insert the

useLegacyV2RuntimeActivationPolicy="true"

attribute into the startup tag. Application should work now.

Reason: .NET 4.0 changed mixed mode assembly loading mechanisms.

Monday, January 11, 2010

Events with anonymous delegate

I subscribed to an event with an anonymous delegate. Later I was in need for a solution to be able to unsubscribe this delegate. This is a simple solution for the problem:

public class ClassName
{
    MouseButtonEventHandler eventHandler;
 
    public ClassName()
    {
        eventHandler = delegate
                                        {
                                            // operations
                                        };
    }
 
    void Functionality()
    {
        if (_subscribe)
        {
            _object.MouseLeftButtonDown += eventHandler;
        }
        else
        {
            _object.MouseLeftButtonDown -= eventHandler;
        }
    }
}

Sunday, December 13, 2009

NUnit and Microsoft Contracts library

I’m using NUnit and Microsoft Code Contracts library to implement unit tests and code contracts (mostly preconditions).

Unfortunately Contracts library throws a generated (internal) exception class that can’t be used as Assert.Throws<ContractException>(…).

Contracts documentation suggests the following code for MSTest framework:

[TestClass]
public  class  Test
{
    [AssemblyInitialize]
    public  static  void   AssemblyInitialize (TestContext tc)
    {
        Contract. ContractFailed+= (sender, e) => {
            e.SetHandled();
            e.SetUnwind(); // cause code to  abort  after  event
            Assert.Fail(e.FailureKind.ToString() + ":" + e.DebugMessage);
        };
    }
}

I wrote the following code to mimic this functionality:

[TestFixtureSetUp]
public void SetUpFixture()
{
    Contract.ContractFailed +=
    (sender, e) =>
    {
        e.SetHandled();
        e.SetUnwind();
        Assert.Fail(string.Format("{0}:{1}", e.FailureKind.ToString(), e.Message));
    };
}

Well, it did not work, I couldn’t make the Assert.Throws structure work. I always got the ContractException exception. Finally I found a blog entry (in German) with a classic solution:

  1. use try/catch block
  2. check exception type name

So here is the working code:

try
{
    // Method under test
}
catch (Exception ex)
{
    Assert.True(ex.GetType().Name == "ContractException");
    return;
}
Assert.Fail("ContractException has not been thrown.");

Monday, December 7, 2009

NDepend

I've started using NDepend Pro on my open-source project. I will try to outline some important features and explain some ideas that differenciate this tool from others like FXCop or ReSharper rules.

What is NDepend?

For me NDepend is a tool for monitoring and improving code quality. It uses software metrics and .NET IL characteristics to help us understand, analyze, visualize and compare different code bases and builds. We learnt code coverage, cohesion, coupling and other code metrics at university, but we hardly had the chance to employ this knowledge (or even understand deeper them). Who wants to calculate them for hundreds of code lines? Well, NDepend just does it instead of us. We can see the internals of code structure and dependencies with just one click!

Costs

NDepend is a free tool for academic and open-source projects. Unfortunately it comes with a cost: you will be restricted with CQL (creating custom code metrics queries) usage, won’t be able to compare builds, won’t be able to integrate test metrics into the dataset and (almost) won’t have Visual Studio integration. I think it’s OK for an open-source project.

Where to start?

NDepend is not an easy tool. Easy to use, but it takes time to learn and understand the metrics and find the proper threshold limits for your project. NDepend team knows it, so they set up a lot of preset thresholds and built-in CQL queries. There are useful demo videos and there is a metrics library. So it’s easy to start using it.

How do I use it?

I use NDepend as a guard. I use other tools (like Resharper, Team System Tools or FXCop) in Visual Studio to check against naming conventions and some other rules. Visual NDepend helps me to understand the structure of my application and recheck some rules, mainly with built-in CQL queries.

I found a circular call in one of my assemblies. It was not trivial to me, I couldn’t have found that without NDepend.

Link: NDepend
Link: software metrics
Link: Inheritance Depth in CQL

Saturday, November 14, 2009

AvalonDock Layout Persistance

Persisting layout using AvalonDock is quite simple. Just call the following methods:

  • DockingManager.SaveLayout(path)
  • DockingManager.RestoreLayout(path)

It’s simple, but it did not work for me. My fault was also simple. You must define the x:Name=”name attribute on the DockableContents and everything will work fine.

Friday, October 30, 2009

Logging proxy

I learnt today that I can create a proxy that intercepts calls to an object, do anything with the call and forward the call to the appropriate object. The same is true for the results. The whole thing is implemented by using a RealProxy implementation. I will demonstrate the functionality with .NET Remoting.

The common interface

namespace Common
{
public interface IServer
{
int Add(int a, int b);
}
}

The server implementation

using Common;

namespace Server
{
class ServerImpl: MarshalByRefObject, IServer
{
#region IServer Members

public int Add(int a, int b)
{
return a + b;
}

#endregion

public override object InitializeLifetimeService()
{
return null;
}
}
}

The server loop

static void Main()
{
// Windows Forms settings
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);

// Remoting loop
RemotingServices.Marshal(new SzerverImplementacio(), "Server");
ChannelServices.RegisterChannel(new TcpChannel(8080), false);

// Windows Froms Window
Application.Run(new Form1());
}

The logging proxy

using System.Runtime.Remoting.Proxies;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Messaging;
using System.Runtime.Remoting.Channels;
using System.Collections;
 
namespace Kliens
{
    public class LogProxy : RealProxy
    {
        String uri;
        MarshalByRefObject obj;
        IMessageSink _sinkChain;
 
        public LogProxy(Type type, string uri) : base(type)
        {
            this.uri = uri;
 
            IChannel[] registeredChannels = ChannelServices.RegisteredChannels;
            foreach (IChannel chnl in registeredChannels)
            {
                if (chnl is IChannelSender)
                {
                    IChannelSender chnlSender = (IChannelSender)chnl;
                    _sinkChain = chnlSender.CreateMessageSink(uri, null, out uri);
                    if (_sinkChain != null)
                        break;
                }
            } 
 
            if (_sinkChain == null)
            {
                throw new Exception("No channel has been found for " + uri);
            }
 
        }
 
        public override IMessage Invoke(IMessage msg)
        {
            Console.WriteLine("LogProxy.Invoke Start");
            Console.WriteLine("");
 
            // Set message URI
            msg.Properties["__Uri"] = uri;
 
            // List call properties
            Console.WriteLine("Call properties:");
            foreach (var key in msg.Properties.Keys)
            {
                Console.WriteLine("{0}: {1}", key, msg.Properties[key]);
                if (key.ToString() == "__Args")
                {
                    Console.WriteLine("Arguments:");
 
                    object[] args = (object[])msg.Properties[key];
                    foreach (var arg in args)
                    {
                        Console.WriteLine("arg: {0}", arg);
                    }
                }
            }
 
            // Process the request mesage
            IMessage retMsg = _sinkChain.SyncProcessMessage(msg);
 
            // List return properties
            Console.WriteLine("Return properties:");
            foreach (var key in retMsg.Properties.Keys)
            {
                Console.WriteLine("{0}: {1}", key, retMsg.Properties[key]);
            }
 
            // Process the return message
            return retMsg;
 
        }
    }
}

Call the server from the client

// Without logging proxy:
// IServer server = (IServer)Activator.GetObject(typeof(IServer), "tcp://localhost:8080/Server");
 
TcpChannel chnl = new TcpChannel();
ChannelServices.RegisterChannel(chnl, false);
 
LogProxy prx = new LogProxy(typeof(IServer), "Tcp://localhost:8080/Server");
IServer server = (IServer)prx.GetTransparentProxy();
MessageBox.Show(server.Add(2, 3).ToString());

Result

All the call end response properties will be listed in the Output window (or in the Console). The call will happen as there were no proxy class taking part in the call.

Apart Remoting this is a good solution for generating any kind of proxies:

  • Virtual proxies
  • Security proxies

RealProxy is a good extension point for an application.