Gunnar Peipman's ASP.NET blog

ASP.NET, C#, SharePoint, SQL Server and general software development topics.

Sponsors

News

 
 
 
DZone MVB

Links

Social

February 2010 - Posts

Using Orca to manage MSI packages

There are many programs that come with MSI installer and not every installer is free of bugs or small problems. If you are building your own installer using Visual Studio you may want to change it before publishing it to users. Here is little overview of my main free tool called Orca.

Orca is free tool you can use to explore and modify MSI files. You can see all the tables of MSI file and look what is inside these tables. On the following screenshot you can see properties table of IIS application warm-up module installer.

Orca: IIS Application Warm-up module installer

It is possible to modify values in tables and set package options. Of course, there are more useful things like package validation, dialog viewer, module merger and transformer you can use to apply custom transforms to your installer.

There are also free alternatives like InstEd and you can find even more if search. I prefer Orca because it is very simple and straightforward. There is not much automagic functionality that does a lot of things for me and I like it. If I need to modify the package I want to see it as it exactly is.

You can find Orca from Windows Server 2003 SP1 Platform SDK as states Microsoft knowledge base article How to use the Orca database editor to edit Windows Installer files. If you don’t want to download Windows SDK-s to your computer, you can download Orca from Softpedia.

Some e-books and .NET 4.0 beta exams

Lately I have found some pretty interesting e-books about different technologies and one announcement about .NET Framework 4.0 beta exams. In this posting I will introduce you books I found and first beta exams.

e-Books

cil C# to IL by Vijay Mukhy is good book for programmers who want to know how C# programs are compiled to Intermediate Language (IL) and how IL works and looks like. For me this book is like lightweight version of Expert .NET 2.0 IL Assembler by Serge Lidin. But it is good book and it helped me to write my blog postings about object to object mapper and how to throw strings instead of exceptions in .NET Framework. Do you really need this book? No, if you are not professional! :)

understanding-ms-virtsol Understanding Microsoft Virtualization Solutions by Mitch Tulloch and Microsoft Virtualization Team is second edition of his famous virtualization e-book published last year. New edition is updated and contains information also about Windows Server 2008 R2. The book covers virtualization topics from desktop to server and it is good reading if you want to know more about virtualization technologies available by Microsoft.

first-look-office-2010First Look: Microsoft Office 2010 is limited time offer from Microsoft Learning. Short, about 200 pages book, is good overview of Microsoft Office 2010 programs, new features and enhancements. I heard from my good friend that he used this book when creating his presentation for local Microsoft Office 2010 day. If he found this book to be useful for such thing as presentation then it should be good reading also for you.

Upcoming exams

Microsoft Beta Exams team announced new .Net Framework 4.0 beta exams that will be available from 31.03 – 20.04.2010.

  • 70-511 TS: Windows Applications Development with Microsoft® .NET Framework 4
  • 70-513 TS: Windows Communication Foundation Development with Microsoft® .NET Framework 4
  • 70-515 TS: Web Applications Development with Microsoft® .NET Framework 4
  • 70-516 TS: Accessing Data with Microsoft® .NET Framework 4
  • 70-519 Pro: Designing and Developing Web Applications using Microsoft® .NET Framework 4

You can read more from Beta Exams blog posting Free Certification Exams.

Simple pager for ASP.NET MVC

I needed simple pager for one of my ASP.NET MVC projects. I mean really simple pager – no new types my code should be aware of, no any other chemistry I don’t really need in early stages. As ASP.NET MVC has nothing to offer I wrote my own *really simple* pager implementation. Here is what I did.

NB! The code here is very fresh and I take it as a fast prototype solution. I provided it to you to give you simple pager you can use without knowing about too much details. You can quickly and easily use it in your ASP.NET MVC applications and application prototypes. Feel free to modify my code if you like.

To get pager built more optimally I created PagerBuilder class. It takes some parameters and based on them it generates pager mark-up when ToString() method is called (just like StringBuilder returns string with its contents when ToString() is called). This is my PagerBuilder.


public class PagerBuilder

{

    private class PagerLink

    {

        public string Title { get; set; }

        public int PageNo { get; set; }

        public string Class { get; set; }

    }

 

    private readonly string _urlTemplate;

    private readonly List<PagerLink> _pagerLinks =
            new List<PagerLink>();

 

    public PagerBuilder(string urlTemplate)

    {

        _urlTemplate = urlTemplate;

    }

 

    public string PagerClass { get; set; }

 

    public void AddPage(string title, int pageNo)

    {

        AddPage(title, pageNo, string.Empty);

    }

 

    public void AddPage(string title, int pageNo,
                        string itemClass)

    {

        var link = new PagerLink

        {

            PageNo = pageNo,

            Title = title,

            Class = itemClass

        };

        _pagerLinks.Add(link);

    }

 

    public override string ToString()

    {

        var builder = new StringBuilder();

        builder.Append("<div");

 

        if (!string.IsNullOrEmpty(PagerClass))

        {

            builder.Append(" class=\"");

            builder.Append(PagerClass);

            builder.Append("\"");

        }

        builder.Append(">");

 

        foreach (var link in _pagerLinks)

        {

            builder.Append("<a href=\"");

            builder.AppendFormat(_urlTemplate, link.PageNo);

            builder.Append("\"");

 

            if (!string.IsNullOrEmpty(link.Class))

            {

                builder.Append(" class=\"");

                builder.Append(link.Class);

                builder.Append("\"");

            }

 

            builder.Append(">");

            builder.Append(link.Title);

            builder.Append("</a>");

        }

 

        builder.Append("</div>");

 

        return builder.ToString();

    }

}


To use pager in views I created extension method called SimplePager for HtmlHelper class. Here is my extension method.


public static string SimplePager(this HtmlHelper helper,
       int currentPage, int pageCount, string urlTemplate,
       string pagerClass)

{

    if (currentPage < 0) currentPage = 1;

    if (pageCount < 0) pageCount = 0;

 

    var pager = new PagerBuilder(urlTemplate);

    pager.PagerClass = pagerClass;

 

    if (currentPage > 1)

    {

        pager.AddPage("&lt;&lt;", 1);

        pager.AddPage("&lt;", 1);

    }

 

    var start = Math.Max(currentPage - 2, 1);

    var end = Math.Min(pageCount, currentPage + 2);

 

    for (var i = start; i <= end; i++)

    {

        if (i == currentPage)

            pager.AddPage(i.ToString(), i, "current");

        else

            pager.AddPage(i.ToString(), i);

    }

 

    if (currentPage < pageCount)

    {

        pager.AddPage("&gt;", currentPage + 1);

        pager.AddPage("&gt;&gt;", pageCount);

    }

 

    return pager.ToString();

}


It needs current page index and page count to generate pager. You must also provide pager class name and URL-template.


<%= Html.SimplePager(Model.CurrentPage, Model.PageCount,
                     "/contacts/page/{0}"
, "pager")
%>


As you can see from example above you can use your model to provide pager with current page and page count. In my case it is okay because repository behind this view returns me paged results so I have no problems with getting current page index and page count.

Currently my pager looks like this after very short playing with styles. Not very nice but it works and some design dude who helps me out can easily make it look very nice.

My ASP.NET MVC pages

Feel free to use and modify my code. If you have questions or suggestions then please drop  your comment here. Happy paging! :)

Code Metrics: Measuring LoC in .NET applications

My previous posting gave quick overview of code metric called Lines of Code (LoC). In this posting I will introduce you how to measure LoC in Visual Studio projects using Visual Studio Code Analysis and NDepend. 

LoC difference in Visual Studio and NDepend

LoC in .NET projects can be measured by Visual Studio and NDepend. Visual Studio and NDepend give different results. How they define their LoC-s?

  • Visual Studio - Indicates the approximate number of lines in the code. The count is based on the IL (Intermediate Language) code and is therefore not the exact number of lines in the source code file. The calculation excludes white space, comments, braces and the declarations of members, types and namespaces (taken from MSDN library article Code Metrics Overview).
  • NDepend - NDepend computes this metric directly from the info provided in PDB files. The LOC for a method is equals to the number of sequence point found for this method in the PDB file. A sequence point is used to mark a spot in the IL code that corresponds to a specific location in the original source (taken from NDepend metrics definiton page). To get better idea about sequence point read Rick Byers blog posting DebuggingModes.IgnoreSymbolStoreSequencePoints.

As Visual Studio and NDepend measure LoC differently they also get different results. Visual Studio measures count of IL instructions while NDepend measures sequence points. So basically Visual Studio gives you greater result than NDepend because on the level of IL instructions it is not possible to know if it was some executable unit of code or was it generated automatically.

Example project

I have simple project to test how Visual Studio and NDepend calculate LoC. My project contains one class. There are only couple of lines of code but it is enough to demonstrate differences.


public class Person

{

    public int Id { get; set; }

    public string FirstName { get; set; }

    public string LastName { get; set; }

 

    public string FullName

    {

        get

        {

            return FirstName + " " + LastName;

        }

    }

}


Before digging deeper I will tell you the results. Visual Studio LoC is 9 and NDepend LoC is 1. This difference looks huge but you will see that it depends directly on different measuring methods.

Visual Studio LoC

When I run Visual Studio code analysis I get the following table.

Visual Studio LoC

Why are automatic properties counted as lines of code? Well… take a look at my blog posting Is Automatic Property Same as Property? This posting shows you clearly how automatic properties work. Behind the curtains they are compiled as usual properties that use attribute to hold property value. FullName uses string concatenation and return – this is why it is handled as two lines of code.

NDepend LoC

NDepend LoC The results table generated by NDepend for Person class is shown on right. You can see that the number of LoC is 1. This is because there is one sequence point generated and it is for FullName property.

NDepend tells us also little bit more. If you look at the results window you can see that methods count for this class is 8 and fields count is 3. It is possible to get results similar to Visual Studio but you have to keep in mind that Visual Studio gives you approximate number, not exact one.

If you have a lot of automatic properties in your classes then the number of methods may be interesting when making first estimates (read my previous entry and warnings about using LoC as estimation method).

NDepend lets you also query analysis results. It has special query language called CQL that is similar to SQL. By example, this query returns all methods that have LoC greater than 15.


SELECT METHODS WHERE NbLinesOfCode > 15


We can also write query for über-bloat methods.


SELECT METHODS WHERE NbLinesOfCode > 100


As you can see syntax is very simple and after playing with queries for a while you are able to write them on the fly. You just have to know what code metrics are and how they are measured.

Conclusion

Measuring LoC with Visual Studio Code Analysis and NDpened are both very simple tasks to do. Visual Studio gives you a different results than NDepend due to different measuring method. If you need complete analysis of your code then NDepend is better way to go because it gives you lot more information than Visual Studio does. NDepend lets you also write queries based on LoC and it makes much easier to analyze your code.

Code Metrics: Lines of Code (LoC)

I started writing series of blog posting about code metrics. I plan to introduce different metrics and explain their meaning. Also I plan to introduce tools you can use to measure those metrics. Where possible I will introduce you how to use one or another metric. The first metric is the simplest one and it is called Lines of Code (LoC).

Purpose

Lines of Code shows how many lines of source code there is in your application, namespace, class or method. LoC can be used to:

  • check the size of code units. If method size is more then 20 code lines then method may be too complex and not so easy to understand. You can also find large classes that must be split to smaller classes.
  • estimate the size of project. You have to understand that LoC is useful estimation characteristic only under certain conditions and until you find some better estimation method (be quick finding it). You can use LoC of one application to estimate another one if they are similar applications by logic, requirements and functionalities. You must be still very careful when using this metric.

My suggestion is to use LoC to monitor the size of your code units. When it comes to software estimation you may probably find better estimation methods.

LoC is not linear estimation characteristic

There is very good book about software estimation: Software Estimation - Demystifying the Black Art by Steve McConnell. Before using LoC as silver bullet I suggest you to come back to the ground and read this book.

Jeff Atwood wrote very good posting about LoC - Diseconomies of Scale and Lines of Code. He cites Steve McConnell:

[Using software industry productivity averages], the 10,000 LOC system would require 13.5 staff months. If effort increased linearly, a 100,000 LOC system would require 135 staff months. But it actually requires 170 staff months.

To get better idea about difference in linear and real estimation take look at the following chart.

LoC is not linear characteristic

I think error at size of 35 staff months is pretty horrible experience for budget, isn’t it?

Productivity cannot be measured by LoC

One of the classic mistakes is using LoC to measure programmers productivity. It is nonsense. One complex algorithm may take about 100 lines of code but the time it takes to make it work may be equal to system that has 10000 lines of code or even more. There is heavy difference in complexity. By example, writing ASP.NET MVC application is pretty easy and straightforward compared to algorithm I mentioned.

Also how can be programmer who wrote 1000 lines of code more effective than programmer who wrote 20 lines of code and achieved same or even better functionality? I see here one more danger – why should programmers write effective and easy to manage code if their work is respected when they write much less effective and way longer code? Measuring productivity this makes strong professionals to seem as horrible ballast in team – do you really want to disrespect or even lose your main workhorses?

Types of LoC

There are two LoC metrics and they differ by measuring method:

  • logical LoC contains only lines of executed code – definitions, namespace imports etc are not considered as executed code. As Patrick Smacchia points out in his blog posting How do you count your number of Lines Of Code (LOC)? the logical LoC is better characteristic because it is not dependent on coding style and language.
  • physical LoC contains all the lines of code and it is measured by parsing files of source code. Take a look at Hackles to get better idea of physical LoC.

It turns out that logical LoC – however you measure it- is way better than physical LoC because it contains less noise.

Conclusion

LoC is good metric to measure size of code units. It can be also used as estimation metric but under very narrow and restrictive limits. It is something you can use when you start estimating but you have to leave it as soon as you find some more exact estimation method. You cannot use LoC to measure progress of project or productivity of programmers – don’t even think about it. :)

In my next postings I will introduce you how to measure code metrics using Visual Studio Code Analysis tools and NDepend.

My object to object mapper source released

Some readers asked me for Visual Studio project of my simple object to object mapper. I am glad to announce that the source code of my mapper is now available for download. It is Visual Studio 2008 project written on C# and besides mapper implementation it contains primitive sample application that shows you how to use my mapper.

vs2008 MyMapper 0.3b (Visual Studio 2008)
zip | 95KB

I made some little changes too – you can set your own property mappings for types if you like. Of course, you can still use automatic mapping that is pretty primitive. Current package contains only LCG (Lightweight Code Generation) implementation of mapper – you can find other (slower) implementations from my blog posting Writing object to object mapper: moving to generics.

If you have question then please feel free to drop a comment here! :)

User controls should never make redirects during GET request

Why is my page redirecting me back to front page although it gets all the data it requires? I was going out of my mind when exploring the problem in one system but this time there was really simple answer: you cannot fully trust the code written by n00bs. Okay, here is my story. :)

Suppose you have page with some user controls. Something like this.

Example page with user controls

There are some URL parameters that user controls use to make sure what data they need to show. I added new context: instead of numeric ID there is another unique parameter that can be used to detect products. ctlFeatured and ctlShoppingCard are written by good coders and ctlDiscount is written by not so well performing dude. After changes everything seems to work, tests show that page gets correct content etc but user is redirected to front page: this the default behavior for missing data (we have our own reasons why it is good).

I was debugging and debugging and everything seems to work fine – but still something redirects me away. Then I started to think about user controls on page. Maybe there is really something horrible done… and I was correct. ctlDiscount was my main suspect because it contains spaghetti code that was not audited yet. What was the problem? Simple – if there is no ID given by URL then redirect user away! This is bad mistake!

User controls should make redirects only during post backs initiated by some of their hosted controls. User controls should never make redirects during GET request.

If user control gets not enough data then it should write entry to error log about it and then hide itself or show error message (or warning). And… never trust the code written by n00bs! :)

Writing object to object mapper: my mapper vs AutoMapper

As my object to object mapper is now almost completed and I am sure it is good idea to stay on LCG (Lightweight Code Generation) I can now compare the performance of my mapper to AutoMapper.

NB! If you are building applications that will run on public servers then use AutoMapper as it is widely used and tested. AutoMapper has tons of features that my little mapper doesn’t have. Also it is easier to get support for AutoMapper if you face the troubles.

Okay, but let’s compare results. Because my mapper has no powerful features and is therefore very light it performs a little bit faster. Take look at the following report.

 My mapper vs AutoMapper

~6 times faster - not bad at all for my little feature-free mapper or what do you think?

There are some improvements I plan to add to my mapper but as these improvements doesn’t affect copying operation. I will write my final version of mapper in near future and provide it in this blog as binary and Visual Studio 2008 project.


kick it on DotNetKicks.com Shout it! 顶 Progg it Shout it
Posted: Feb 12 2010, 08:10 AM by DigiMortal | with 8 comment(s)
Filed under: , ,
Writing object to object mapper: moving to generics

In my previous posting about object to object mapping Writing object to object mapper: first implementations I wrote first and simple implementations of mapper. These implementations based heavily on reflection. In this posting I will boost up mapper performance by using generics.

In most parts the code here is same as before but instead of laying heavily on objects we make use of generics so we can maybe achieve better performance than before.

Base class and property map

Property map is still the same but object base is moved to generic methods.


public class PropertyMap

{

    public PropertyInfo SourceProperty { get; set; }

    public PropertyInfo TargetProperty { get; set; }

}

 

public abstract class ObjectCopyBase

{

 

    public abstract void MapTypes<T, TU>();

    public abstract void Copy<T, TU>(T source, TU target);

 

    protected virtual IList<PropertyMap>
        GetMatchingProperties<T, TU>()

    {

        var sourceProperties = typeof(T).GetProperties();

        var targetProperties = typeof(TU).GetProperties();

 

        var properties = (from s in sourceProperties

                          from t in targetProperties

                          where s.Name == t.Name &&

                                s.CanRead &&

                                t.CanWrite &&

                                s.PropertyType == t.PropertyType

                          select new PropertyMap

                          {

                              SourceProperty = s,

                              TargetProperty = t

                          }).ToList();

        return properties;

    }

 

    protected virtual string GetMapKey<T, TU>()

    {

        var className = "Copy_";

        className += typeof(T).FullName.Replace(".", "_");

        className += "_";

        className += typeof(TU).FullName.Replace(".", "_");

 

        return className;

    }

}


These changes to non-abstract methods are marginal and we don’t have to do these changes if we don’t want. They don’t affect performance as we see later.

ObjectCopyReflection

Here is the generic implementation of ObjectCopyReflection.


public class ObjectCopyReflection : ObjectCopyBase

{

    private readonly Dictionary<string, PropertyMap[]> _maps =
        new Dictionary<string, PropertyMap[]>();

 

    public override void MapTypes<T, TU>()

    {

        var source = typeof(T);

        var target = typeof(TU);

        var key = GetMapKey<T, TU>();

        if (_maps.ContainsKey(key))

            return;

 

        var props = GetMatchingProperties<T, TU>();

        _maps.Add(key, props.ToArray());

    }

 

    public override void Copy<T, TU>(T source, TU target)

    {

        var key = GetMapKey<T, TU>();

        if (!_maps.ContainsKey(key))

            MapTypes<T, TU>();

 

        var propMap = _maps[key];

 

        for (var i = 0; i < propMap.Length; i++)

        {

            var prop = propMap[i];

            var sourceValue = prop.SourceProperty.GetValue
                              (source, null);

            prop.TargetProperty.SetValue(target, sourceValue,
                                         null
);

        }

    }

}


Running this implementation gives us 0,0242 ms as result. It is practically same as before and moving this implementation to generics had no impact on performance.

ObjectCopyDynamicCode

Now let’s take ObjectCopyDynamicCode implementation.


public class ObjectCopyDynamicCode : ObjectCopyBase

{

    private readonly Dictionary<string, Type> _comp =
        new Dictionary<string, Type>();

 

    public override void MapTypes<T, TU>()

    {

        var source = typeof(T);

        var target = typeof(TU);

 

        var key = GetMapKey<T, TU>();

        if (_comp.ContainsKey(key))

            return;

 

        var builder = new StringBuilder();

        builder.Append("namespace Copy {\r\n");

        builder.Append("    public class ");

        builder.Append(key);

        builder.Append(" {\r\n");

        builder.Append("        public static void CopyProps(");

        builder.Append(source.FullName);

        builder.Append(" source, ");

        builder.Append(target.FullName);

        builder.Append(" target) {\r\n");

 

        var map = GetMatchingProperties<T, TU>();

        foreach (var item in map)

        {

            builder.Append("            target.");

            builder.Append(item.TargetProperty.Name);

            builder.Append(" = ");

            builder.Append("source.");

            builder.Append(item.SourceProperty.Name);

            builder.Append(";\r\n");

        }

 

        builder.Append("        }\r\n   }\r\n}");

 

        var myCodeProvider = new CSharpCodeProvider();

        var myCodeCompiler = myCodeProvider.CreateCompiler();

        var myCompilerParameters = new CompilerParameters();

        myCompilerParameters.ReferencedAssemblies.Add(
            typeof(LinqReflectionPerf).Assembly.Location
        );

        myCompilerParameters.GenerateInMemory = true;

        var results = myCodeCompiler.CompileAssemblyFromSource
            (myCompilerParameters, builder.ToString());

 

        var copierType = results.CompiledAssembly.GetType
                         ("Copy." + key);

        _comp.Add(key, copierType);

    }

 

    public override void Copy<T, TU>(T source, TU target)

    {

        var key = GetMapKey<T, TU>();

        if (!_comp.ContainsKey(key))

            MapTypes<T, TU>();

 

        var flags = BindingFlags.Public | BindingFlags.Static |
                    BindingFlags.InvokeMethod;

        var args = new object[] { source, target };

        _comp[key].InvokeMember("CopyProps", flags, null, null,
                                 args);

    }

}


The result is 0,0059 ms and it is also same as before. So we don’t have any luck here too.

ObjectCopyLcg

Before all hope is gone let’s see what LCG (Lightweight Code Generation) implementation of mapper thinks about generics.


public class ObjectCopyLcg : ObjectCopyBase

{

    private delegate void CopyPublicPropertiesDelegate<T, TU>
        (T source, TU target);
 

    private readonly Dictionary<string, object> _del =
        new Dictionary<string, object>();

 

    public override void MapTypes<T, TU>()

    {

        var key = GetMapKey<T, TU>();

        if (_del.ContainsKey(key))

            return;

 

        var source = typeof(T);

        var target = typeof(TU);

 

        var args = new[] { source, target };

        var mod = typeof(Program).Module;

 

        var dm = new DynamicMethod(key, null, args, mod);

        var il = dm.GetILGenerator();

        var maps = GetMatchingProperties<T, TU>();

 

        foreach (var map in maps)

        {

            il.Emit(OpCodes.Ldarg_1);

            il.Emit(OpCodes.Ldarg_0);

            il.EmitCall(OpCodes.Callvirt,
                        map.SourceProperty.GetGetMethod(), null);

            il.EmitCall(OpCodes.Callvirt,
                        map.TargetProperty.GetSetMethod(), null);

        }

        il.Emit(OpCodes.Ret);

        var del = dm.CreateDelegate(
                  typeof(CopyPublicPropertiesDelegate<T, TU>));

        _del.Add(key, del);

    }

 

    public override void Copy<T, TU>(T source, TU target)

    {

        var key = GetMapKey<T, TU>();

        var del = (CopyPublicPropertiesDelegate<T, TU>)_del[key];

        del.Invoke(source, target);

    }

}


The result is 0,0019 ms and it is ~4.5x better than before. Although LCG implementation was not the fastest one before it is now the best implementation we have.

Results

Let’s put previous and current results to table and let’s compare them.

Implementation Non-generic Generic Difference
ObjectCopyReflection 0,0240 ms 0,0242 ms ~1,0 x
ObjectCopyDynamicCode 0,0058 ms 0,0059 ms ~1,0 x
ObjectCopyLcg 0,0084 ms 0,0019 ms ~4,5 x

As we can see then first two implementations gave different results but differences were very-very small. We can practically say that there were no changes in performance. ObjectCopyLcg gave us ~4.5x times better result when we moved to generics.

Conclusion

This posting is good example about how generics are not silver bullets that fix performance problems automagically because they know the types. In our situation we achieved better results only in one implementation while other implementations stayed practically the same. In my next object to object mapper posting I will compare my results with AutoMapper.


kick it on DotNetKicks.com Shout it! 顶 Progg it Shout it
Visual Studio 2010 RC is available

VS2010 VS2010 RC is out now and available for MSDN users since now. Other guys have to wait until tomorrow when VS2010 RC is made publically available. Reading first news I discovered that most important thing is improved performance of VS2010 RC IDE. All your feedback is welcome to VS2010 RC Connect site.

To find out more follow these links:

Before installing RC you must uninstall all previous versions of VS2010 and .NET Framework 4.0. It seems like another long nights of hacking and discovering new stuff are waiting for us. :)


kick it on DotNetKicks.com Shout it! 顶 Progg it Shout it
More Posts Next page »