Feeds:
Posts
Comments

The NPanday team finally released NPanday 1.2, coming with quite a few fixes and also some features. In total there were 55 issues fixed. You can find the release notes here. The download is found at CodePlex.

If you haven’t heard of NPanday yet: It brings Apache Maven to the .NET world. In addition to numerous maven plugins for various .NET-related build tasks it comes with a Visual Studio Addin as well.

Major Improvements

  • Compatible with Maven 3
  • MSI-based installer for the Visual Studio AddIn
  • Improved Mono-compatibility
  • Improved Documentation
  • Many bug fixes
  • Improved type names… dotnet-library instead of library, e.g. (NPanday – Project Types)

Hidden Features

We have also implemented two almost undocumented features. We are not yet sure about how those will evolve, that’s why we don’t make noise here…

  1. There is now a custom-lifecycle-plugin that registers the NPanday Types, but only binds the install and the deploy phases. You can then configure plugin executions as you need them in the project pom.
  2. <plugin>
      <groupId>npanday.plugin</groupId>
      <artifactId>custom-lifecycle-maven-plugin</artifactId>
      <version>1.2</version>
      <extensions>true</extensions>
    </plugin>
    
  3. The new type dotnet-archive allows you to package and reference dotnet libraries along with their satellite assemblies, debug symbols or other necessary files. When resolving a dotnet-archive dependency you can use unpack-dependencies to get the files, and for packaging them up, you want to use the Maven Assembly Plugin. For future releases we tend to implement native support for dotnet-archive.

Planned for next releases

  • Support for .NET 4
  • Code Coverage with NCover
  • Localized Satellite Assemblies
  • Update everything to the new types (dotnet-*)

You may want to read Brett Porters’s post as well: NPanday 1.2 Released – .NET integration for Apache Maven

Eric Lippert is on the C# Compiler team and has written a series of posts on this topic that are an absolute must-read!

  1. Part One
  2. Part Two: Array Covariance (and Why is covariance of value-typed arrays inconsistent?)
  3. Part Three: Method Group Conversion Variance
  4. Part Four: Real Delegate Variance
  5. Part Five: Higher Order Functions Hurt My Brain
  6. Part Six: Interface Variance
  7. Part Seven: Why Do We Need A Syntax
  8. Part Eight: Syntax Options
  9. Part Nine: Breaking Changes
  10. Part Ten: Dealing With Ambiguity
  11. Part Eleven: To infinity, but not beyond

MSDN

The information here is quite “flat”, but still worth a read.

More

Category Theory

The names covariance and contravariance in C# derive from co- and contravariant functors described in category theory.

Hope that helps!

Just a plain list of types from the .NET 4.0 Base Class Library where Microsoft has added support for covariance (out) and contravariance (in).

in System

// Delegates
Action<in T1[..in T16]>
Func<out TResult>
Func<in T1[..in T16], out TResult>
Comparison<in T>
Converter<in TInput, out TOutput>
Predicate<in T> 

// Interfaces
IComparable<in T>
IObservable<out T>
IObserver<in T>

in System.Collections.Generic

IComparer<in T>
IEnumerable<out T>
IEnumerator<out T>
IEqualityComparer<in T>

in System.Linq

IGrouping<out TKey,out TElement>
IOrderedQueryable<out T>
IQueryable<out T>

I just reused some code I wrote a couple of years ago, and thought I’d share it here.

It’s not about the best ways to resize images. If that is what you search for, have a look at this :-)

It’s rather some code for calculating the size of the target image from the originals size while applying one of four rules:

  • Fit: Often you want to fit the image into a box – but without stretching it. So if you have a image that is 50×100 and you want to fit it into 50×50, the result is 25×100. If the original is 100×50, the result would be 50×25. Getting it?
  • Stretch: Not to useful, but sometimes needed :-)
  • FixedHeight: Maintain the ratio, adjust to height.
  • FixedWidth: Maintain the ration, adjust to width.

Usage

Pretty straight-forward, I think.

var _100_50 = new Size(100, 50);
ResizeType.Fit.CalcNewSize(_100_50, new Size(50, 50), true)
    .Satisfy(s => s.Width == 50 && s.Height == 25);

var _50_100 = new Size(50, 100);

ResizeType.Fit.CalcNewSize(_50_100, new Size(50, 50), true)
    .Satisfy(s => s.Width == 25 && s.Height == 50);

ResizeType.Stretched.CalcNewSize(_50_100, new Size(500, 500), false)
    .Satisfy(s => s.Width == 50 && s.Height == 100);

ResizeType.FixedHeight.CalcNewSize(_50_100, new Size(0, 50), false)
    .Satisfy(s => s.Width == 25 && s.Height == 50);

* The Satisfy-Method is from SharpTestEx.

Code

Have fun! :-)

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Text;

namespace lcorneliussen
{
    public interface IResizeType
    {
        Size CalcNewSize(Size currentSize, Size newSize, bool resizeIfSmaller);
    }

    /// <summary>
    /// Offers some helpful methods for image resizing.
    /// </summary>
    public class ResizeType
    {
        /// <summary>
        /// Returns the new size by fixed height.
        /// </summary>
        public static IResizeType FixedHeight = new FixedHeightResizeType();

        /// <summary>
        /// Returns the new size by fixed width.
        /// </summary>
        public static IResizeType FixedWidth = new FixedWidthResizeType();

        /// <summary>
        /// Returns a size wich fits in a target size.
        /// </summary>
        public static IResizeType Fit = new FitResizeType();

        /// <summary>
        /// Stretches a image to the given size.
        /// </summary>
        public static IResizeType Stretched = new StretchedResizeType();

        private static int CalcNewHeight(int currentWidth, int currentHeight, int newWidth)
        {
            float ratio = (float)newWidth / (float)currentWidth;
            float newHeight = currentHeight * ratio;

            return (int)newHeight;
        }

        private static int CalcNewWidth(int currentWidth, int currentHeight, int newHeight)
        {
            float ratio = (float)newHeight / (float)currentHeight;
            float newWidth = currentWidth * ratio;

            return (int)newWidth;
        }

        private class FixedHeightResizeType : IResizeType
        {
            public Size CalcNewSize(Size currentSize, Size newSize, bool resizeIfSmaller)
            {
                int height = newSize.Height;

                if (!resizeIfSmaller)
                {
                    if (height > currentSize.Height) height = currentSize.Height;
                }

                int newWidth = CalcNewWidth(currentSize.Width, currentSize.Height, height);
                return new Size(newWidth, height);
            }
        }

        private class FixedWidthResizeType : IResizeType
        {
            public Size CalcNewSize(Size currentSize, Size newSize, bool resizeIfSmaller)
            {
                int width = newSize.Width;

                if (!resizeIfSmaller)
                {
                    if (width > currentSize.Width) width = currentSize.Width;
                }

                int newHeight = CalcNewHeight(currentSize.Width, currentSize.Height, width);
                return new Size(width, newHeight);
            }
        }

        private class FitResizeType : IResizeType
        {
            public Size CalcNewSize(Size currentSize, Size newSize, bool resizeIfSmaller)
            {
                int width = newSize.Width;
                int height = newSize.Height;

                int newWidth = currentSize.Width;
                int newHeight = currentSize.Height;

                if (!resizeIfSmaller) // break, if newSize allready fits in currentSize
                    if (currentSize.Height < height && currentSize.Width < width)
                        return new Size(currentSize.Width, currentSize.Height);

                if(width != newWidth) // shrink or expand to width
                {
                    newHeight = CalcNewHeight(currentSize.Width, currentSize.Height, width);
                    newWidth = width;
                }
                if (newHeight > height) //shrink to fit height, if neccesarry
                {
                    newWidth = CalcNewWidth(newWidth, newHeight, height);
                    newHeight = height;
                }

                return new Size(newWidth, newHeight);
            }
        }

        private class StretchedResizeType : IResizeType
        {
            public Size CalcNewSize(Size currentSize, Size newSize, bool resizeIfSmaller)
            {
                int w = newSize.Width;
                int h = newSize.Height;

                if (!resizeIfSmaller)
                {
                    if (w > currentSize.Width) w = currentSize.Width;
                    if (h > currentSize.Height) h = currentSize.Height;
                }

                return new Size(w, h);
            }
        }
    }
}

* this code on gist

Groovy is a nice language. I currently use it for writing maven plugins and for doing scripting tasks in the realm of build automation.

Poor mans integration with .NET or other systems is the command-line. Groovy has built-in support for that:

"myprog".execute()

And if you need parameters:

["cmd", "/C", "cd"].execute()

But there are some problems with how to wait for the process and retrieve the streams. Often you just want the output back – and you want to make sure that the command exited with no error.

There is also a ant-integration in groovy. So I wrote a little wrapper that makes using ant’s exec-task feasible:

mixinAntExec() // has to be called once
// prints the stdout
// if the error code is != 0,
// it throws an exeption with
// helpful information
println ("myprog".antExec())

def result = ["myprog", "/fail"].antExec(false)
println (result.exitValue) // error code
println (result.error) // err out
println (result.text) // std out

This script can either be pasted to the bottom, or included on the script path:

def mixinAntExec() {
    String.metaClass.antExec = {failOnError=true -> antExec([delegate], failOnError)}
    ArrayList.metaClass.antExec << {failOnError=true -> antExec(delegate, failOnError)}
}

def antExec(command, failOnError=true) {
    def commandLiteral = command.collect{it.contains(' ') ? '"' + it + '"' : it}.join(' ')

    println "ant exec with: ${commandLiteral}"

    def ant = new AntBuilder()
    ant.exec(outputproperty:"text",
             errorproperty: "error",
             resultproperty: "exitValue",
             failonerror: false,
             executable: command[0]) {
               if (command.size()>1)
                   arg(line:command[1..-1].collect{it.contains(' ') ? '"' + it + '"' : it}.join(' '))
             }

     def result = new Expando(
         text: ant.project.properties.text,
         error: ant.project.properties.error,
         exitValue: ant.project.properties.exitValue as Integer,
         toString: {text}
     )

     if (failOnError && result.exitValue != 0){
         throw new Exception("""command failed with ${result.exitValue}
executed: ${commandLiteral}
error: ${result.error}
text: ${result.text}""")

     }

     return result
}

The last couple of weeks I worked a lot with NPanday which brings maven to .NET. But this post is not about NPanday but rather about the workflow for maintaining a personal branch and uploading patches.

I’m not a committer, but I had to do some changes to NPanday. I still want to version my changes. I also want to contribute patches, when I fix bugs that apply to the current trunk.

NPanday is hosted on Codeplex, and though accessible via the SvnBridge. So I chose to give git svn a try.

I also want to host my changes on github.

The Workflow

  • Once
    • Clone a svn repo to a local-git
    • Create a branch for svn updates, say codeplex
    • Create a GitHub repo and push both branches
  • Repeatedly
    • Do your work on master
    • Commit and push your work
    • Update codeplex from subversion and push it
    • Merge codeplex to master
  • Contribute and Commit
    • How to create and submit patches from our master
    • How to commit changes back to codeplex

The How-To

I don’t want to mess around with npanday, so I created a empty test-project on codeplex.: [SAMPLE PROJECT] Branch and Patch with GIT

Setup (Windows)

On mac you simply use mac ports, on linux I have no clue.

  • Install SVN binaries and add to %PATH% (download)

  • The binary mysys doesn’t come with git svn anymore, so you have to compile it yourself. Is not as hard as it sounds. Just download the fullinstall – it will run the compile for you. (download 1.7.0.2 , downloads) Don’t forget to add it to the path, too.

I’ll do everything on the command line. Red is SVN, green is GIT – they are in separate folders.

I use pictures. Type it yourself! It will help you to learn it.

Don’t be afraid reading the command line either. It’s like code! You’ll get used to it, so did I.

Once

Checkout and commit a text fileimage

Init and fetch the commited revision using svn git:

image

Now, since we want to do changes, lets create a branch codeplex but remain on master and do changes.

image 

We should make sure, that the branch codeplex is untouched:

image

I also created a project on github. So lets push it over there. Read how to setup your private key and connect here.

image

Now we have the two commits on the master:

tmp2E0B

And only one on codeplex:

tmpE826

Now we change our “subversion”-file:

image

And then we update it using git svn rebase on the codeplex branch. Sorry for not having accepted the certificate before. But its live! :-)

image Result:

tmpD8EB

Now we want to have that change over on our work branch.

image

Voilá:

tmpF6A9

Now, this is our repo:

image

Enough for today. Let’s se what we covered:

Recap

  • Once
    • We initialized the empty codeplex repo with a single-line file.
    • Clone a svn repo to a local-git
      We used git svn init and fetch to get the codeplex contents in a local git repository.
    • Create a branch for svn updates, say codeplex
      We created the branch
    • Create a GitHub repo and push both branches
      We pushed both master and codeplex
  • Repeatedly
    • Do your work on master
      We added a file to our master.
    • Commit and push your work
      We pushed it to master. Both the source svn and codeplex branch remain untouched.
    • Update codeplex from subversion and push it
      We added a line and checked it into svn and then we got it into our codeplex branch did that.
    • Merge codeplex to master
      We did that too.

More soon! Probably next Friday:

  • Contribute and Commit
    • How to create and submit patches from our master
    • How to commit changes back to codeplex

In a dream world a developer should code all the day, right? Well, a very common task beside coding though is to estimate tasks of manifold kinds. Estimating though, sucks.  For badly educated product managers and for many of our customers a estimate equals to a personal commitment. Therefore you better get it right the first time!

In many projects at itemis we use something we call WBS which stands for work breakdown structure. The term itself is not new, but rather PMI vocabulary. But the combination with three-point-estimates and some statistics makes it a very powerful tool.

Work Breakdown Structure

WBS is not more than breaking your tasks down to small units that can easily be estimated. It’s just a estimation technique and can be applied in any traditional or agile process.

Three-point Estimates

Three-point estimates help you to incorporate the risk into your estimate. Lets say I discovered a simple task, by breaking down the big project of writing a particular blog entry about WBS.

Example Task: Graphically illustrate the WBS domain model

Now think about how you potentially would solve this. The simplest solution would be to create a diagram of the classes I already have in Visual Studio. That would be almost no work. But those look to cheap and they contain the wrong details. So I’ll do it manually. Probably using OmniGraffle – a diagramming tool for Mac only.

Now, ask yourself three questions. How many hours would it take to finish this task, if…

  • … I’m highly motivated, in the middle of a diagramming rush, and no tools crash, no one calls me, nobody asks for help on some other task, …? You see where this goes. Since there is a great stencil available that I’ve used earlier, I’d just drag the classes on the canvas and the auto-layout will probably be good enough. Lets say, in the best case I’ll need about 1 hour to illustrate the domain model.
  • … I’ve done this before, and I know, visualizing is always tricky. Based on my experience I’d expect a little bit of trouble for the layout. It will probably also be necessary to adjust the stencil a little bit. Also I’d ask some of my colleagues for their opinion and then do some adjustments. In the average case I should be done in 4 hours.
  • … I’ve had a busy week, it’s Monday morning 9 am and I am absolutely not in the mood to work at all let alone do anything creative. OmniGraffle crashes all the time, and the stencil turns out to not do the job. The telephone rings all the time, and my room mate happens to have a loud discussion with his PM because he just spent 3 days on a task he estimated with 2 hours. Also I have to start from scratch once because I forgot to save, and another time because I just messed up the layout. This is not really likely to happen all at once, but in the worst case I’d be on the tasks for 12 hours. I couldn’t imagine how it could take longer.

Now I’ve got three numbers. In the best case 1 hour, at average 4 and in the worst case 12 hours.

Statistics

Now, you can neither tell your customer nor your PM that you need one and up to 12 hours to finish the task. For one single task this might even be correct, but when you have a set of many tasks it’s not very likely that the worst case applies for every task.

I’m not really into the details of the statistics, but I’ll try to explain them from what I’ve understood.

There is two interesting values that can be calculated per task. Let us just name

  • The pert is an educated guess. It considers the average case (A) for times more reliable than best (B) and worst (W) case.
    The pert formula: (B + 4A + W)/6
  • The variance is a value that indicates how different best and worst case are. There is a magic number involved assuming that in 50% of the cases, the actual hours will less or equal to the pert. This is based on a suggestion from the book Software Estimation by Steve McConnell, page 121 ff.
    The variance formula: (W–B / 1.4)^2

Applying these values to our task, we will result in following table. I also added another simple task

Task Best Average Worst Pert Variance
Graphically illustrate the WBS domain model

1

4

12

4.83

61.73

Embed the domain model illustration in the post*

0.08

0.25

0.50

0,26

0.09

Sums

1.08

4.25

12.5

5.10

61.82

Standard Deviation**        

7.86

* A small task with a small variance has little impact. As you would expect. But if the variance grows, even small tasks have great impact. As in reality.

** The standard deviation is calculated by powering the sum of all variances with 0.5.

The first interesting result is, that by a certainty of 50% I’d manage to fulfill the two tasks within 5.1 hours.

Based on the standard deviation combined with the normal distribution (Gaussian curve) we can create a table indicating by which certainty (in %) we are done within X days.

Since the variance in our case is higher than the expected value, some of the numbers won’t make sense.

Each of the percentages have a factor of the variance with which the result deviates from the pert value.

Formula: Pert + (Variance * Variance Factor)

by a certainty of

variance factor

done within (hours)

10% -1.28 (negative number)
16% -1 (negative number)
20% 0.84 (negative number)
25% 0.67 (negative number)
30% 0.52 1.01
40% 0.25 3.13
50% 0 5.10
60% 0.25 7.06
70% 0.52 9.19
75% 0.67 10.37
80% 0.84 11.70
84% 1 12.96
90% 1.28 15.16
98% 2 20.82

Result

No I can assure, that the task will be done within 20 hours by a certainty of 98%. 

This number is just to high, isn’t it? But did it never happen to you that a task took 4 times longer than expected? Not so uncommon, I’d say.

Maybe I wouldn’t put this number on the customer offer, but that is not what it is about either.

What it is about is knowing you risk and make educated decisions.

But not yet enough.

Team estimates

All those calculations still rely on one person doing expert estimates. So what about having multiple persons that estimate the tasks and then combining the results?

The concept is simple.

  1. Most likely two persons do the breakdown together. Either one does a first draft and the other reviews it, or what I rather prefer is that they pair on this step.
  2. The two or more do the estimations separately.

Why separately? Well, it is not about blaming people but about gathering quality data. And having a high variance between to peoples estimates on a certain task indicates a high level of uncertainty about what this task means in practice. The earlier you identify those spots, the better.

Just get the two to talk and eliminate the uncertainty. They can then either agree on a estimate, or what at least should happen they redo the estimates with a lower variance. Both results raise the quality of your data.

There is different ways of combining multiple estimates. The one that makes the most sense is taking the lowest best case, the average of the average cases and the highest worst case. This would give you a quite reliable result.

Checklists

Especially meant to improve the quality of the worst case estimates the estimating person is guided by a checklist about typical things to consider when estimating software projects.

The current ones we use at itemis now include around 50 entries four categories: Preconditions, Things typically forgotten, Non-functional requirements and Other crosscutting concerns

The Experiment codenamed “Lillesand”

3962721542_195313c680[1] “Lillesand” is beautiful a city in the south of Norway. I just spent my Christmas holidays there. But for this project it’s just a codename.

Currently we use a Excel sheet that helps us creating the WBS. This works fine. But its limited. It lacks support for gathering multiple WBS in a project and the calculations for team estimates are still done manually.

Since this is much about data and functions, I thought I’d try to build this using the technologies leveraged by SQL Server Modeling formerly called Microsoft Codename “Oslo”.

I already posted on the migration to the latest CTP. I’ll publish the sources soon.

I don’t really know where this will go, but I think it will be interesting to follow.

While writing an article about co- and contravariance in .NET I stumbled over some funny C# behaviors.

Given a simple domain model of animals (Reptile is base of Snake and Turtle), will this actually work?

And if not, what will happen? Will it even compile?

Reptile[] reptiles = new[]
  {
    new Snake("Leo"),
    new Snake("Lucy")
  };

reptiles[0] = new Turtle("Platschi");

Quite obvious, still odd. :-)

GREAT! Thanks for the answers!

I think @thinkbeforecoding had the best answer. Justin Chase, Björn Rochel and Stefan Lieser also got it right.

Here is what happens:

  1. It compiles!
  2. The type inference will infer a Snake[] from new[] because all elements are Snake.
  3. The Snake array will then be implicitly casted to the Reptile array reptiles because C# supports covariance for Array element types.
  4. Line 7 also compiles fine. But the covariance support is unsafe, hence read-only. The Snake-Array behind the scenes can’t handle Turtles.
  5. A ArrayTypeMismatchException is thrown at runtime.

In C# 4.0 there will not be safe variance for Arrays either. There can never be safe co- and contra-variance for read-write-interfaces or types, because you need co-variance for reading (out) and contra-variance for writing (in).

Back in October 2008 Microsoft announced “Oslo” as a new and world-changing modeling platform. While it always consisted of a language, an editor and a repository the community seemed to be mostly interested in the language “M” and it’s grammar features for creating new domain specific languages.

The feedback could be summarized to:

Great! We love model-driven. We love DSLs. But why the heck SQL?

After that they got engaged with that community. Chris hosted the DSL Dev Con. And Doug released “M” under the Open Specification Promise and founded the “M” Specification Community. Mathew Wilson implemented M in JavaScript. Hugo Brunelier elaborated on the possibilities of bridging it with Eclipse Modeling.

Many wrote, spoke and blogged about it. The fellow hope was, that Microsoft could bring model-driven development to a broader audience and by that increase both productivity and quality in software development.

For that community the renaming of “Oslo” to SQL Server Modeling was a slap in the face. Many stated that they were disappointed by Microsoft’s decisions.

Let’s look into the reasoning and the real consequences of that rename.

Even though I think it was a wise decision business-wise both the timing and the messaging was really bad.

The Repository and “Quadrant” were closely tied to SQL right from the beginnings of “Oslo”. The schema, constraints and functions part of “M” had and mostly still has only one implementation: also SQL.

But the languages part of “M” also referenced to as “MGrammar” had nothing to do with SQL at all and it still doesn’t have much to do with it today either.

“M” should have been split out from “Oslo” before the rename and everybody would have been happy.

So where is this going now?

“M” and “Quadrant” today are still code names. The only thing that has a final name is the repository part of “Oslo” which is now named SQL Server Modeling Services. And I think we agree that that is a OK name.

Most probably “M” will not become SQL Server Modeling M and neither will “Quadrant” be named SQL Server Modeling Quadrant.

I think the final “M” will be as much SQL as Entity Framework and OData are SQL today. All those are developed within the same group and I expect it to merge anyway.

“Quadrant” will probably replace the part in SQL Server Management Studio that enables browsing and editing of SQL data – which is horrible today anyway. It also has the potential of replacing Access as a platform for Information Workers.

And maybe some day we’ll see ideas from “Quadrant” in Excel.

Future of DSL Development with Microsoft Tools

Visual: There was a hope, that “Quadrant” could be a better DSL Toolkit. Those teams didn’t talk to each other, but now they do. I think MS gave up on visual DSLs with “Quadrant”. Instead we’ll see the DSL Toolkit getting more attention. In some Demos at PDC we saw diagrams in Visual Studio working together with SQL Server Modeling. That were already DSL Tools operating on “M” models.

Textual: “M” is at maximum a third of the “Oslo” vision. And the languages part again is only a subset of “M”. Maybe that helps seeing the priorities in the big context.

But still the commitment is alive. The November CTP has some great new features. For example more powerful “M” projections for grammar rules or basic debugging support.  Probably some day this will merge with the DSL Tools and we’ll have both graphical and textual DSLs support right within Visual Studio. I think and hope that the connection to SQL will not be very strong in the future.

Model-driven Development

As often when Microsoft starts (mis)using existing terms they or at least many of their employees just don’t get it. At least not in the first place.

An application that uses “M” to define the M in MVC is not automatically model-driven. It’s just a normal application that operates on data as most applications do. If you want to argue like that, then every C# file and all SQL table rows are models.

In my perception model-driven is, when models become part of the implementation. The Workflow Foundation is a good example for what model-driven means. You model something that is the source of truth for your application – instead of C# code.

If tools help building things like the workflow foundation based on either visual or textual DSLs, using interpreters or code generation, then they truly support the vision of model-driven software development.

image_12[1]

Keith and Woody interviewed me at PDC last year and now the show is out.

It was a pleasure to talk to you guys. Thanks also to Don Xml who introduced me to them.

I should listen through it once more just to count how often I say “right?” and “stuff”. :-)

Older Posts »