Sponsors

The Lounge

Wicked Cool Jobs

Current Bloggers

Partners

 

Wikis

  • You have not yet contributed to any pages.

Software Release Management - Why You Can’t And Shouldn’t Force People to Use the Latest Version

Posted by Rob Reynolds, Wednesday, January 25, 2012 (1,875 views)

As software creators we don't get to decide what version of our tools / libraries that people use. If we try to force them, our users will go somewhere else.

Update: What Type of Software This Applies To

This post talks of tools, applications and libraries. Things that end up in the users hands. This does not apply to SaaS or websites. These do not end up in the hands of the users in the same sense.

For those of you who immediately think of Chrome or Firefox, which are applications that end up in the users hands, those apply to this post as well. They have nearly perfected a silent upgrade experience, but if they ever mess up that experience, users can choose to use something else. And I believe there is a way to opt out as well (not easily achieved but possible).

Software Release Management

I write software. Much of it is open source. I have multiple versions of my products out there. Even with newer versions available that fix bugs and bring about new features, I still find people using older versions. Even though I have a better newer version that fixes some of the bugs they are dealing with, they are still using an older version. Think about that for a second. There must be a good reason right? Let’s state this in an official sense.

As a software creator you release software. You put a release out there and people use that release. You delineate different releases by a concept of versioning. People use a particular version of your release. You release newer versions of your software that has fixes and enhancements. You hope users upgrade to the latest release when it is available.

I’ve stated five facts and finished with a hope. If you can accept those as facts, we can move on. If we can’t, then you might want to stop reading now because we are never going to agree. If you are a developer like me, you really want people to always use the latest version of your software, so you might be able to accept the last statement as a fact for you. I really want people to always use the latest release of my software as I have went through the trouble of testing it and making it better.

Now let me change some terms for you. Software release management is really a fancy way of saying package management. A software release could be better termed a package. So to restate, as a software creator, you release packages. You put a package out there and people use that package. You delineate different packages by a concept of versioning. People use a particular version of your package. You release newer versions of your package that has fixes and enhancements. You hope users upgrade to the latest package when it is available.

The Hope Versus The Force

I say “hope they upgrade” because you really can’t control that aspect. You can try. You can delete the older versions. You can refuse to have older versions available. You can tell users that they should and need to upgrade. But you put it out there once and it is now out there forever. People will find a way to get to the particular version they need. Or they will go elsewhere. Users speak with their feet.

I find attempting to force a user to do something is both an exercise in futility and a great way to guarantee that you have less users overall.

So people must want to use a particular version of a product. Let’s examine this a little more. Why on earth would someone use an older version of a product when a newer, better, less buggier version is available?

Why Do Users Use Older Versions?

Users use older versions of our packages and they have great fundamental reasons for doing so:

  • It reduces their risk.
  • It guarantees that users of their library (that has a dependency on your library) have a good experience.
  • It guarantees that the product that they have tested is the same product that gets into the hands of consumers.
  • It guarantee their product builds successfully and the same way each time.

In fixing a product and making it better and less buggier, you may actually be breaking someone’s ability to use a newer version. And you have no guarantee to the user that this version doesn’t have flaws of it’s own. Right? Otherwise there would only be one version that ever had fixes in it. We wouldn’t need to release newer versions with fixes, only enhancements. But we don’t. We fix things we thought worked and we fix things we tested but missed some crazy edge case. This is why we go down this path of release management. This is software development.

So people get a certain version and they use it. Users upgrade to the latest version of software when they are ready, not when the software creator is ready. People depend on certain versions or on a range of versions. In reality I can't force someone to use the latest version. If I try, they will find the version they need through the powers of the internet or find another way. Accepting that, I can give them a way to see it and help them fall into the pit of success.

From the User Perspective

Shifting to the perspective of the user, I might use your library in my own software. Being able to build my product, even if it means it is using an older version of your package that has bugs, is worlds more important to me and my users. We'll get to your latest version when we can test that it doesn't break our product. But don't try to force me to upgrade to your latest version or I will find another way. I'm not saying that with your package but in all packages the newer version may be buggier than the current buggy version we are using. We don't know and you can’t guarantee that it doesn’t, even with extensive testing. Testing doesn’t prove the absence of bugs, only the absence of errors that you know. I digress.

It’s an evil that we know versus and evil that we don’t. Or put another way, it's a buggy version we know versus a buggy version we don't.

If it’s a tool, we need to ensure that our usage of your product still meets our expectations. We need to test it even though you did and make sure it still works for our needs and scenarios. Where it doesn’t we need to decide if that means we can shift our expectations and upgrade. But we are not going to blindly upgrade and just use the latest version because the software creator believes that is best.

Can you cover the millions of dollars that we might lose by taking on a newer version of your product? If you can give me that guarantee, as a user I will gladly pass that risk on to you.

Final Thoughts

Whether you agree or not, as software creators we don't get to decide what version of our tools / libraries that people use. We just don’t have that luxury. If we try to our users will go somewhere else. So we make it easy for them to upgrade so they will want to. We make the upgrade experience painless so they will want to. We need to be good stewards.

Filed under: , , , ,
Discuss (7)

Missing Silverlight Resources and ASP.Net security

Posted by Derik Whittaker, Wednesday, January 25, 2012 (666 views)

Have you ever had an error crop up when debugging an application which has made you simply want to pull each hair out of your head one by one with a pair of tweezers because that would be less painful than debugging the error? Today I had just this happen to me.

Today when I hit F5 to launch our Silverlight application I received the following exception :

image

The body of this error message is

Line: 56
Error: Unhandled Error in Silverlight Application
Code: 2108   
Category: InitializeError      
Message: Failed to download the splash screen    

Of course since I have the debugger I was going to attach to it, but sadly that was NO HELP.  When reading error you notice it says that it failed to download the splash screen. This is really odd because when looking in the source it is there…  In an effort to ‘remove the problem’ I removed the line of code from our ASPX page which setup the splash screen as a resource, the line below.

<param name='splashscreensource' value='SplashScreen.xaml' />

Thinking that this would solve my issue, at least for now, I hit F5 again.  Things were different this time, but sadly not for the better.  Now in place of getting the error message I simply got the default ‘blue dots’ from silverlight indicating that the xap was trying to load.  This was really odd.  I did what any developer would do, I hit F5 3-4 more times thinking that the problem would just magically go away, hey it does happen, but as you can guess it did not go away.

Because I had been making a bit of changes in the code and it was possible that I could have accidently really FUBARED my code base I shelved my code, blew away my ENTIRE branch and did a fresh pull.  Yea, that did not either.

So my on branch was dead, but my co-worker who is in the same branch was able to launch and run the app just fine.  In another effort to see if it was my branch code or my machine I decided to pull down the trunk (the parent of this particular branch) to see if I had the issue there… Yea no, that code worked just fine.

Because I knew it was not my machine it had to be code.  I decided to start diffing the files I thought were causing the issues such as our default.aspx page, our login page along with a few other files.  As you may have guessed NONE of these files were different.

Because I had been beating my head against this for greater than an hour I decided that I should move on to something else and come back to this later (I guess I was still holding out for the code fairy to magically fix my stuff while I was away).

Well later came and I had to go back to my branch to fix a production issue and this issue was still there.  This time however things were a bit different, no the code fairy did not do her magic, my co-worker said ‘hey I got that a few minutes ago’.  I was both elated and pissed at the same time.  I was elated because maybe NOW I could solve my issue.  I was pissed because this was the same co-worker I had talked to about this issue a few hours back and NOW they knew how to solve the issue.

So what was the issue?  My co-worker was playing around with some security settings in our web.config file and had accidently committed is changes.  It was these changes that was causing my issue.  What did he change?  He did 2 things

1) He setup a deny ALL authorization rule
image

 

 

2) He setup other rules to only allow a few pages to be open as such
image

The 2nd change was not a huge issue, it was the 1st one that was killing me.  Because he had turned off anon access to the site my xap could not load and because my xap could not load the splash screen could not be presented to the user and for what ever reason Silverlight decided that in place of providing a meaningful message it would simply say it could not find my splash screen resource.

Since I knew the issue I was able to change my rule from deny to allow (in #1) and re-run the application…. finally I could fix bugs I created Smile

The moral of the story here is that if you get an error saying you cannot access a resource in your xap file double check that IIS has access to the xap because if it does not you may get this issue.

The other moral of the story is that it should be 100% legal to cane a co-worker who commits a change that breaks you and does not even realize it. Ok caning may be harsh, at least they should buy you a beer.

Till next time,

Filed under:
Discuss (0)

Boo-yah!!! Caliburn.Micro v1.3 RTW is Here

Posted by Rob Eisenberg, Friday, January 20, 2012 (3,591 views)

I’m extremely pleased to announce the release of Caliburn.Micro v1.3.  This is a great release with many bug fixes and several API improvements. We also support several new platforms. Here’s the highlights:

  • Support for WP7 Mango
  • Support for Silverlight 5
  • Basic MVVM Support for WinRT/Metro
  • Awesome improvements to ViewModelLocator/ViewLocator which allow easier customization of conventions.
  • Improved Design-Time Support for Conventions

Thanks to the great community who provided awesome feedback during this release cycle. Thanks also to those who spent time to provide fixes and pull requests for bugs as well as for API improvements. I’d like to add a special thanks to Chin Bae for excellent work on making our ViewLocator and ViewModelLocator both more extensible and more accessible for common customizations.

We’re still just getting started. Enjoy the new bits and see what you can build!

Testing framework is not just for writing… tests

Posted by Krzysztof Koźmic, Wednesday, January 18, 2012 (2,026 views)

Quick question – from the top of your head, without running the code, what is the result of:

var foo = -00.053200000m; 
 
var result = foo.ToString("##.##");

Or a different one:

var foo = "foo"; 
var bar = "bar"; 
var foobar = "foo" + "bar"; 
var concaternated = new StringBuilder(foo).Append(bar).ToString(); 
 
var result1 = AreEqual(foobar, concaternated); 
var result2 = Equals(foobar, concaternated);
 
 
 
public static bool AreEqual(object one, object two) 
{ 
    return one == two; 
}

How about this one from NHibernate?

var parent = session.Get<Parent>(1); 
 
DoSomething(parent.Child.Id); 
 
var result = NHibernateUtil.IsInitialized(parent.Child);

The point being?

Well, if you can answer all of the above without running the code, we’re hiring. I don’t, and I suspect most people don’t either. That’s fine. Question is – what are you going to do about it? What do you do when some 3rd party library, or part of standard library exhibits unexpected behaviour? How do you go about learning if what you think should happen, is really what does happen?

Scratchpad

I’ve seen people open up Visual Studio, create ConsoleApplication38, write some code using the API in question including plenty of Console.WriteLine along the way (curse whoever decided Client Profile should be the default for Console applications, switch to full .NET profile) compile, run and discard the code. And then repeat the process with ConsoleApplication39 next time.

 

The solution I’m using feels a bit more lightweight, and has worked for me well over the years. It is very simple – I leverage my existing test framework and test runner. I create an empty test fixture called Scratchpad.

scratchpad

scratchpad_fixture

 

This class gets committed to the VCS repository. That way every member of the team gets their own scratchpad to play with and validate their theories, ideas and assumptions. However, as the name implies, this all is a one-off throwaway code. After all, you don’t really need to test the BCL. One would hope Microsoft already did a good job at that.

If you’re using git, you can easily tell it not to track changes to the file, by running the following command (after you commit the file):

git update-index --assume-unchanged Scratchpad.cs

scratchpad_git

With this simple set up you will have quick place to validate your assumptions (and answer questions about API behaviour) with little friction.

scratchpad_test

 

 

So there you have it, a new, useful technique in your toolbelt.

Discuss (8)

Approval testing – value for the money

Posted by Krzysztof Koźmic, Monday, January 16, 2012 (1,597 views)

I am a believer in the value of testing. However not all tests are equal, and actually not all tests provide value at all. Raise your hand if you’ve ever seen (unit) tests that tested every corner case of trivial piece of code that’s used once in a blue moon in an obscure part of the system. Raise your other hand if that test code was not written by human but generated.

 

As with any type of code, test code is a liability. It takes time to write it, and then it takes even more time to read it and maintain it. Considering time is money, rather then blindly unit testing everything we need to constantly ask ourselves how do we get the best value for the money – what’s the best way to spend time writing code, to write the least amount of it, to best cover the widest range of possible failures in the most maintainable fashion.

Notice we’re optimising quite a few variables here. We don’t want to blindly write plenty of code, we don’t want to write sloppy code, and we want the test code to properly fulfil its role as our safety net, alarming us early when things are about to go belly up.

Testing conventions

What many people seem to find challenging to test is conventions in their code. When all you have is a hammer (unit testing) it’s hard to hit a nail, that not only isn’t really a nail, but isn’t really explicitly there to being with. To make matters worse the compiler is not going to help you really either. How would it know that LoginController not implementing IController is a problem? How would it know that the new dependency you introduced onto the controller is not registered in your IoC container? How would it know that the public method on your NHibernate entity needs to be virtual?

 

In some cases the tool you’re using will provide some level of validation itself. NHibernate knows the methods ought to be virtual and will give you quite good exception message when you set it up. You can verify that quite easily in a simple test. Not everything is so black and white however. One of diagnostics provided by Castle Windsor is called “Potentially misconfigured components”. Notice the vagueness of the first word. They might be misconfigured, but not necessarily are – it all depends on how you’re using them and the tool itself cannot know that. How do you test that efficiently?

Enter approval testing

One possible solution to that, which we’ve been quite successfully using on my current project is approval testing. The concept is very simple. You write a test that runs producing an output. Then the output is reviewed by someone, and assuming it’s correct, it’s marked as approved and committed to the VCS repository. On subsequent runs the output is generated again, and compared against approved version. If they are different the test fails, at which point someone needs to review the change and either mark the new version as approved (when the change is legitimate) or fix the code, if the change is a bug.

 

If the explanation above seems dry and abstract let’s go through an example. Windsor 3 introduced way to programmatically access its diagnostics. We can therefore write a test looking through the potentially misconfigured components, so that we get notified if something on the list changes. I’ll be using ApprovalTests library for that.

[Test]
public void Approved_potentially_misconfigured_components()
{
    var container = new WindsorContainer();
    container.Install(FromAssembly.Containing<HomeController>()); 
 
    var handlers = GetPotentiallyMisconfiguredComponents(container);
    var message = new StringBuilder();
    var inspector = new DependencyInspector(message);
    foreach (IExposeDependencyInfo handler in handlers)
    {
        handler.ObtainDependencyDetails(inspector);
    }
    Approvals.Approve(message.ToString());
}
 
private static IHandler[] GetPotentiallyMisconfiguredComponents(WindsorContainer container)
{
    var host = container.Kernel.GetSubSystem(SubSystemConstants.DiagnosticsKey) as IDiagnosticsHost;
    var diagnostic = host.GetDiagnostic<IPotentiallyMisconfiguredComponentsDiagnostic>();
    var handlers = diagnostic.Inspect();
    return handlers;
}

 

What’s important here is we’re setting up the container, getting the misconfigured components out of it, produce readable output from the list and passing it down to the approval framework to do the rest of the job.

Now if you’ve set up the framework to pup-up a diff tool when the approval fails you will be greeted with something like this:

approval_diff

You have all the power of your diff tool to inspect the change. In this case we have one new misconfigured component (HomeController) which has a new parameter, appropriately named missingParameter that the container doesn’t know how to provide to it. Now you either slap yourself in the forehead and fix the issue, if that really is an issue, or approve that dependency, by copying the diff chunk from the left pane to the right, approved pane. By doing the latter you’re notifying the testing framework and your teammates that you do know what’s going on and you know it’s not an issue the way things are going to work. Coupled with a sensible commit message explaining why you chose to approve this difference you get a pretty good trail of exception to the rule and reasons behind them.

 

That’s quite an elegant approach to a quite hard problem. We’re using it for quite a few things, and it’s been giving us really good value for little effort it took to write those tests, and maintain them as we keep developing the app, and the approved files change.

 

So there you have it, a new, useful tool in your toolbelt.

Discuss (3)

How to Show a deleted List Item with a Strike Through in XAML

Posted by Derik Whittaker, Sunday, January 08, 2012 (1,193 views)

When building applications it is very common to have a set of screens which are basically list/edit screens.  And when having these list/edit screens it is also common to allow users to delete a row.  In this post I am going to show how you can add a neat little UI wrinkle to your deleting action which will be visually appealing but will also allow users to undo their changes with ease.

If you take a look at the screen shot below you will notice that I have a data grid with 2 line items.  You should also notice that at the far right of each row is a ‘Red X’ which can be used to delete that selected row.  Commonly when you have this type of delete action the row will be removed from the UI in real time.  Having the row removed in real time is ok but it does give the user an easy way to undo their actions prior to committing their changes.  What I would like to do is change this.

image

In the screen shot below you can see how we have accomplished the ability to mark a row as being deleted yet still give the user the ability to undo a given deletion.  What we have done is 2 things.

  1. In place of actually removing the row from the grid we implemented the strike through to show the user that row will be removed when the save their changes.
  2. We removed the delete icon and replaced it with the add icon

image

Since we know what we want to accomplish how do we actually do it.

  1. Setting up your model to have Deleted bool property
    In order for this whole thing to work you will need to have some sort of bool property on your underlying model which stored the Deleted state of a given row.

    	private bool _deleted;
            public bool Deleted
            {
                get
                {
                    return _deleted;
                }
                set
                {
                    _deleted = value;
    
                    OnPropertyChanged(() => Deleted);
                }
            }
  2. Setting up your XAML to have the strike through
    In my XAML we are using the stock DataGrid for Silverlight and we are templating each column in the grid.  For the columns which we want to implement the strike though we need to add some xaml which will only be visible WHEN Deleted flag of the given row is true.  Here is snapshot of our XAML

    image

    Things to pay attention to in the above XAML are
    1) We have both a TextBlock and a Rectangle element in our cell, however the Rectangle’s visibility is being set based on the Deleted flag.  To set this visibility we are using a BooleanToVisiblity converter (will put that code at the end of this post)
    2) In the above case the margin on the Rectangle is Margin=”4,0,0,0” and this is because it is far left column in our grid and we don’t want the line to butt up against the edge.  In the middle columns we don’t want a margin in order to appear to be a complete line.  However in our far right column we want to setup the margin as Margin=”0,0,4,0” in order to not butt up against the right hand edge.

  3. Setting up your XAML to swap action buttons based on the deleted state
    To enable the swapping of our buttons based on the Deleted flag we basically will do the same as above w/ the strike through lines but in place of the visibility being swapped on a Rectangle we will do it on a Button element.

 

BoolenToVisibilityConverter Code

	public class BooleanToVisibilityConverter : IValueConverter
	{
        public Visibility TrueValue { get; set; }
        public Visibility FalseValue { get; set; }

        public BooleanToVisibilityConverter()
        {
            TrueValue = Visibility.Visible;
            FalseValue = Visibility.Collapsed;
        }

		public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
		{
            if (value == null)
            {
                return Visibility.Collapsed;
            }

			return ((bool) value) ? TrueValue : FalseValue;
		}

		public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
		{
			throw new NotImplementedException();
		}
	}

As you can see you can implement a slick UI which shows the user an item has been deleted with very little effort.

Till next time,

Filed under: ,
Discuss (2)

How I Lost, Regained and then Turned Down an MVP Award

Posted by Rob Eisenberg, Wednesday, January 04, 2012 (32,546 views)

What Happened To Me

I’d say that 2011 was a pretty good year for me as a .NET open source developer. After all, Caliburn.Micro had it’s first official release in April 2011 just in time for the Mix Open Source fest. At the festival, the framework had a great showing. I had tons of people literally coming up to me and dumping *all* their voting tokens into my bucket. In fact there were so many people constantly standing around my booth that my bucket didn’t even get collected for counting in the official vote. Thankfully someone standing around realized this and helped to remedy the situation. Needless to say, it was a successful event. Over the next several months I did two additional non-trivial releases and then began work on the v1.3 release. I also added support for Silverlight 5, WP7 Mango and preliminary support for WinRT/Metro. Furthermore, I began refactoring the entire framework so that it could be modularized into “feature” packages allowing a variety of different uses of the framework via Nuget. I even tested CM’s EventAggregator and IoC container to make sure they would run without issue on iOS and Android devices via Unity3d. In addition to the actual framework development, I wrote documentation, blogged, fixed dozens of bugs and added new features. I also participate daily in the Caliburn.Micro forums which currently have about 1k discussions. Caliburn.Micro is now used as the core enabling framework for thousands of applications across WPF, Silverlight and various versions of WP7. Depending on the day, Caliburn/Caliburn.Micro is the second or third most trafficked Xaml-related open source project in existence.

I’m not trying to toot my own horn here. I’m just trying to set up a context. Considering the enormous amount of work in both creating the project and supporting the community…you can imagine my surprise when I received the “form letter” stating that my MVP was not being renewed because I hadn’t accomplished enough in the last 12 months….and what I did do did not “stand out” in the community. Here’s the actual quote:

“The MVP Award is presented to individuals for their past year’s contributions to online and offline communities, which stand out from others in the communities that focus on Microsoft technologies. Your contributions were diligently evaluated over the past year against the contributions of others in the Silverlight community.  As a result of this evaluation, you were not awarded as a MicrosoftMVP for the January 2012 award cycle.”

Now, I’m not really “attached” to being an MVP. I don’t attach a lot of self-worth or emotional satisfaction to it. It’s a nice thing to have though. So, I was really caught off guard by this and wondered how the MVP program could come to the conclusion that I hadn’t significantly contributed in the last year.

What I Did

Being surprised as I was, and not being too fond of “generic” letters , I made one simple tweet:

“Apparently Caliburn/Caliburn.Micro and my support of it is not a ‘good enough’ contribution for Microsoft. I lost my MVP this year.”

The Community Response

Immediately following this tweet, a storm of people responded with great affection for my work and general encouragement. I want to say thank you to everyone who responded so kindly. Paired with the encouragement was a general sense of befuddlement around how the MVP program could make such a conclusion. Apparently, I wasn’t the only surprised individual.

I thought to myself “mistakes happen.” But as I was surveying the twitter-verse, I also learned that Jeremy Miller (StructureMap, FubuMVC, Storyteller) and Daniel Cazzulino (Moq) also lost their MVPs; two other prominent open source developers. Now I had had some problem during the re-evaluation process indicating my new MVP Lead clearly didn’t understand the nature of open source. When I was up for renewal, he asked me to fill out a rather ridiculous spreadsheet. If you could see it, you would notice something missing? There’s no category for Open Source!!! There’s not even a way to report it. I had this problem in previous years when I was asked to update my online MVP profile (a hideously painful UX by the way). The program uses that to evaluate you as well. Guess what? There’s no way to report Open Source work!!! Do you see a trend here?

--Start Rant

The thing that really disturbed me was that my MVP Lead didn’t know who I was or understand the nature of my contributions. What is it that an MVP Lead does anyways? I can’t tell. I get a useless mass email every week or so telling me things about Microsoft I don’t care about. Half of the time it isn’t even readable due to bad formatting, etc. My Lead never contacted me personally during the year. When I came up for renewal, I had to *defend* why I should have my award renewed using a bad Excel spreadsheet and a really bad online form which don’t even allow me to capture my real contributions. Shouldn’t it be an MVP Lead’s job to know his MVPs and what it is they are doing? Seriously. I sat down and calculated how much time it would take me to fill out the Excel form and the online form, plus writing a custom report for everything that wasn’t able to be captured via those broken mechanisms. I took that number of hours and multiplied it by my hourly consulting rate and determined that the money I would make working exceeded the material value of the MVP award. Haven’t I given enough free work to Microsoft? This isn’t a personal attack on *my* MVP Lead. I don’t know the guy. But, I wonder whether the role of MVP Lead is improperly defined or under-defined, because I know that I’m not the only person who has had this exact problem repeatedly.

--End Rant

Microsoft Employees to the Rescue

Also following my tweet, a number of Microsoft employees stepped in to investigate.  I have to thank them here personally. Much thanks to you (in no particular order) Tim Heuer, Pete Brown, Joe Healey, Glenn Block and Scott Hanselman. At one point I heard that this issue had even been escalated internally to Scott Guthrie. It’s truly an honor that so many well known and respected individuals *inside* Microsoft stepped up to personally investigate my situation. Thank you again. This is a tremendously good thing and points out something of great importance. Over the years I’ve very rarely had negative experiences with individual Microsoft employees. But, I’ve almost always had bad experiences interacting with groups, programs, etc. It seams that somehow the opinions of the individuals are lost in the system. That’s a real shame.

If the opinion of many trusted Microsoft employees and the opinion of so many community members is not reflected in the MVP Award, then there certainly is a problem with the program…or I don’t understand what the program is.

An MVP Again…for a few hours

Thanks to the work of the gentlemen listed above, I was informed last night that I was being re-awarded an MVP for the 2012 year. I understand this sort of thing never happens. But, I’d already had several days to reflect on the MVP program and had several conversations with various people leading to several realizations listed above and several more detailed below. I was very unsettled.

Why I Turned Down the MVP

This morning I responded to the award email with a respectful decline. Below are some of the reasons I chose to no longer be a part of the program and why I doubt I will participate again, unless serious reform happens.

Becoming an MVP

One of the problems with the MVP program is that the whole thing is basically a mystery. Here’s where I first knock heads with the program. I value transparency and openness, even if it’s difficult or sometimes painful. The MVP program does not value openness. That’s why it’s basically a mystery how you get nominated for an MVP or what you have to do to get one. Let me do a little exposé here. In my case, I’m fairly sure that my local Developer Evangelist saw the work I was doing in the local community and submitted me. That’s a good thing and it’s probably fairly common. But what happens from there? It’s my understanding that it’s completely out of DPE’s hands at that point. Who knows? From what I can tell, if the MVP program is interested in you, you then have to submit proof of your accomplishments to them. I remember doing this. It’s not like a normal award where the organization does the work to investigate your contributions and then decides whether or not to give you an award. No. If you are being considered for nomination, you literally have to *sell* yourself to the MVP program…and selling is exactly what you are doing. Want to know why? Have you noticed that the MVP disciplines are strictly organized around internal product groups, regardless of how hindering to the particular MVP discipline it appears to be? An example of this is that Client AppDev, Silverlight, WP7 and Blend are all separate MVP groups even though they should be unified. Because they are different products, they are different MVPs (actually, they should all be the same product, but that’s a subject for another blog post). Do you know why this is? I’ll tell you: because each product group literally gets an MVP “budget” which they use to “purchase” MVPs for the year. Personally, I’m offended by this notion. But it would take drastic re-organization of the MVP program to fix it.

General Life as an MVP

Now you can just imagine how this division along product lines and MVP purchasing might affect things. Because Microsoft’s product teams are notorious for not only being non-communicative with one another but are often pitted against one another by the upper level management…the various product teams can develop a vastly different set of values and beliefs with respect to interaction both internally and with the outside world. Depending on what MVP discipline you are a part of…and the nature of your contributions…you may have a great experience or you may be in store for hell. If the product group you are associated with is open, such as ASP.NET, you can expect lots of interaction, incorporation of your feedback into the product and probably a deep respect of open source work. If your product team is something like WP7, you can expect much less communication, very little change to the product based on your feedback and probably…they don’t even know what open source is.

My Life as an MVP

As for myself, it’s clear that my major contribution is through an open source framework. What a fool I was…there’s a certain insanity in building an open source framework on top of a proprietary UI stack. Back when I was awarded the MVP, I was given the Client AppDev designation, which basically means WPF (but for some reason, contrary to what I’ve said above, also included WinForms..interesting how they had WPF and WinForms in the same group but not WPF and Silverlight…but I digress…or do I?). Back then Xaml tech wasn’t so secretive. When Silverlight came along, they moved me into that group. That group was different. Silverlight was kept tightly sealed. When I was a Client AppDev, I actually felt like Rob Relyea and John Gossman were my kin. When I became a Silverlight MVP, I felt like I was an outsider being graced with a little tiny window to peer in on things. I say all that because when I started on Caliburn, while I was working on a proprietary platform, it felt more open. But when Silverlight came along, things changed. WP7 was even worse than Silverlight…and WinRT/Metro…well…they didn’t talk to anyone. Now that Xaml has moved out of the Developer Division and into the Windows division, it’s only going to get worse.

Secret Societies

I’ve already mentioned how the organization of the MVP groups along product lines can be a hindrance to everyone. WPF, Silverlight, WP7, Metro and Blend…which are all used by the same group of people, are actually different MVP groups. As a Silverlight MVP…I had no access to anything happening with WP7. I had no knowledge of WinRT/Metro. I had no knowledge of Blend or any mechanism to directly interact with that product team. Now, Caliburn.Micro spans all of these technologies, but I could really only talk to Silverlight product team members…and a few of my old WPF comrades. But would it surprise you if I told you the organizational absurdity went even farther. Did you know there are “insiders” groups. “Insiders” for a particular product group have more privileged knowledge than MVPs and more opportunities for direct interaction. Some MVPs are also insiders, but not all. Some insiders are not MVPs. But wait, there’s more. There’s also the TAP program….which seams to have more privileged connections and knowledge. To this day, I don’t know how one gets in a TAP program. I was in the WP7 Tap for about two days. Some guys already in the program were talking in the TAP forums about getting Caliburn.Micro working on WP7. They yelled loud enough and the powers that be invited me, since it seamed that significant apps were likely to be built with my framework. Unfortunately, things went public very shortly after that and the TAP was closed. LOL. But it doesn’t end there. It seams, based on observation, that there are even more secretive groups…who pretty much know everything the product team knows. These guys don’t have a name and I don’t know how you get into that. Though, I’m pretty sure it has to do with being “chummy” to the right people. Childishness. The bottom line is that there are too many levels of secrecy and too many and the wrong types of divisions to enable an effective feedback loop. I don’t know if this is true of all MVP groups, but it was with Silverlight and it has got worse with each successive Xaml platform. Now that Xaml is in Windows, I don’t expect anyone to be able to provide decent feedback.

Fruitlessness

Since things are so improperly organized, there are really only a few occasions where one can really provide good feedback on the product. Unfortunately, after three years as an MVP, I have to say that not a single bit of feedback I provided resulted in any sort of change to the product. With the Silverlight team..and almost always with the Blend team (when I could actually run one of them down), I would get some response like “yes, we’ll have to have a conversation about that.” And I’d be thinking…”isn’t that why I’m here at the MVP summit talking to you now?” But they never seamed to want to engage in a real discussion on *anything* that affected me, my project or my clients. I had this happen every year at the summit. I had even more outrageous things happen in email and at BUILD. On the insiders email list (when I finally got on it), I tried to start a conversation about Convention over Configuration and improvements to tooling that would help support those scenarios and generally make tool extensibility better. Somehow I managed to get into a private email thread of the Blend team where they could engage me on that. You know what they said when I tried to continue the conversation? They said “we don’t want to discuss that right now.” Ok…thanks. That made me really mad. Why am I an MVP again? But the real treat was at BUILD. I managed to track down two of the Blend PMs. I first talked to the PM in charge of the JavaScript Blend work. I told him about what I was building in JavaScript. He was really interested and wanted to follow up with me on what I was building and how it would work inside Blend. Then I took several steps to the right to talk to a Blend PM working on the Xaml side of things. I tried, once again, to discuss CoC. I know for a fact these guys either don’t understand it or don’t think it’s important in software at all. Well, they listened for a moment, then I asked about improving the tooling so I could have a plugin mechanism by which to improve that scenario for my customers. They were very not-helpful. I tried to bring up issues of developer productivity and better strategies for building applications. In a nutshell, the PM basically said to me “we don’t care about developers…they aren’t part of our use cases.” I was pretty enraged by that. See how the product team’s culture affects the effectiveness of the MVP program? My main point though is that nothing I ever said or did affected any product team’s work. Nothing. It was a waste of time and energy…and an emotional drain.

MVP Quality

Now I want to tread lightly here with how I say this….not all MVPs are created equal. I’m going to be vague here. I met an MVP once for Technology X. It turned out that she had never built anything with Technology X and wasn’t overly knowledgeable about it. She liked Technology X a lot though. Each day she would scan her RSS feeds and post about 8 - 10 links on Technology X. That’s why she had her MVP. It looks good on a review doesn’t it? I blogged 365 posts on Technology X this year!!  Now, I’ve met some MVPs in various areas that were brilliant and obviously contributing a lot. But, I’ve met a fair share of MVPs who not only were not experts on the technology, but didn’t make half the contribution that other developers I knew did, who were never awarded MVPs. Not all MVPs are equal. If you are an employer, or looking for a speaker, expert, consultant…whatever; you cannot assume that just because that person has an MVP that they know what they are talking about. It’s sad, but this describes a noticeable number of MVPs.

One more word on MVP quality with respect to division along product team lines. You should never hire a highly product-specific MVP to help advise you on technology choices. I hope you realize the built-in problem with that. I know very few Technology X MVPs who would tell you not to use Technology X, even if there was a better, cheaper, faster way to build your solution. Be wary.

Open Source

I just want to say a little more about this. As I mentioned, there’s nothing about the MVP program that explicitly allows for recognition of open source work. It’s hard to get nominated for it and it’s even harder to renew with it. MVP leads who play a major roll in the renewal process may not be technical at all and even may not understand Open Source. Since I’ve mentioned how MVPs are linked to product groups, you might guess that the effectiveness of your MVP as an OSS developer is entirely dependent on that particular product group’s understanding of and interest in OSS. In a group related to ASP.NET or JavaScript, developers on the team are likely to have run open source projects themselves. In a group like Silverlight or WP7, they are likely to have never done such a thing…and not even have a clear idea of what is involved. I really came face to face with this when my non-renewed MVP…got renewed. Why? Well, it felt like a sort of “benefit of the doubt” renewal. Here’s the advice I was given from the renewal email, elided:

EDIT: I removed this quotation because a good friend of mine was honest enough to remind me that quoting a personal email is neither professional nor polite. I repent of that.

--Start Rant

What!? I released one of the most popular Xaml-related OSS project this year. I did multiple version releases, nuget packages, podcasts, documentation, forum support…the list goes on. What more do you want from me? And what should I do next year…because Caliburn.Micro is so popular, that in order for me to do something bigger for next year…I’d have to dump it entirely….completely abandoned it and build something totally different…something even more popular for Silverlight!? How could I do that to my community? That’s not even nice. No, in 2012, I’m going to continue to fix bugs, add features, add platform support and do awesome things with Caliburn.Micro. I love my own community and I’m going to continue to work hard and support them.

--End Rant

Now this kind of comment clearly expresses a deep lack of understanding for both the value of a project like Caliburn.Micro and the amount of time and resources it takes to maintain both the project and the community. If your OSS project is successful, it’s not just something you do one year and then move on to something else the next. In fact, building the first version of Caliburn.Micro was the easy part! It’s everything that’s happened afterwards and what is happening now that is hard work and will continue to be.

Unfortunately, Microsoft just doesn’t have a way of recognizing OSS developers who improve their platform. The MVP program doesn’t do this and the product teams may not either. In fact, Balmer has explicitly said he isn’t creating any policy around OSS…he’s totally dodging it entirely. This leaves the decision up to the individual teams…which sometimes goes well, but often times does not. That’s irresponsible leadership.

Career Affects

No one ever hired me as a consultant because I had an MVP. They hired me because of my open source work and my recognized expertise in UI architecture. The company I’m working for…I don’t even think they know what an MVP is. They hired me because they know *me* and know I can help them with their particular problem. I would say the personal career benefits of having an MVP are a wash except…

With Microsoft’s less than above the bar treatment and communication about Silverlight over the last year or so, you might imagine this could effect MVPs associated with the program. I’ve heard a lot of horrible stories in the last year. I didn’t have anything terribly bad happen to my business, but I was quite embarrassed recently. I was attending a .NET user group meeting, of which I am the president. Somehow I or someone else mentioned that I was a Silverlight MVP. I don’t remember the detail about how it came up, but I do remember what happened next. Someone laughed at me. Literally, I was made fun of because my MVP had the word Silverlight attached to it. Now, I’m just not willing to endure mockery for the sake of Silverlight, especially since I understood exactly why he was laughing at me. It has got to where being a “Silverlight” MVP is bad for my career.

My Happiness

Looking over the last three years, I’ve definitely been a less happy, more frustrated developer. I’m sure it’s linked to the sort of fake “value” being a Silverlight MVP gave me. Basically, they give you a couple of cheep gifts, then they pretend to listen to your feedback, while not actually doing anything. Year after year of that and you get really unhappy. It’s demoralizing. You start to realize that you really are a commodity. You are purchased by a product group and kept around as long as they perceive they need you…your feedback is allowed, but not effective. Again, it’s probably not the case for all MVPs, it depends on the groups. I just don’t need that in my life.

Conclusion

I’m saying goodbye to the MVP program even after I was re-offered the award for 2012. If you’ve read this far, you can probably see why I made that decision. I’m really positive about the future of Caliburn.Micro and hopeful regarding my JavaScript framework. I think 2012 is going to be a wonderful year. If someone seriously reforms the MVP program or if Microsoft decides to properly recognize and reward open source efforts, then, maybe I’ll let them give me an award. But for now, I don’t need to suffer any more. I’m free and I’m going to do great things.

API design challenge – builder

Posted by Krzysztof Koźmic, Saturday, December 31, 2011 (1,880 views)

Now that Windsor 3 is released I can concentrate on some of my other ideas and projects. While working on one of them, called Cartographer, I encountered an interesting API design problem.

 

I have a class (a builder to be precise) that has a task of setting up a central object (an IMapper implementation) in Cartographer (If you’ve ever used Autofac, it is somewhat analogous to ContainerBuilder). What is interesting about it, is I have three goals for that class:

  1. Provide API for high level configuration and extension points that are universal to and intrinsic to any IMapper implementation.
  2. Provide API for low level configuration of the default IMapper implementation that the builder creates, that will meet the following criteria:
    1. Not force user to customize anything, as the default setup should be enough to get started in most cases.
    2. Allow users to easily swap/extend parts of the dependency chain of the default mapper.
    3. Work well and be natural both with and without IoC container .
  3. Be simple and discoverable to the users (and provide good Intellisense experience).

How would you design the API for this class?

 

Oh, and happy new year.

Filed under:
Discuss (0)

Building Async WCF Services in Silverlight with Channelfactory

Posted by Derik Whittaker, Saturday, December 17, 2011 (3,136 views)

If you have created any silverlight applications which need to communicate to a WCF Endpoint you know that you must communicate with WCF via Async actions.  As you may know there are multiple ways to get your Silverlight application to communicate with a WCF service.  One way is to simply create a Service Reference, aka proxy.  The other is to use the ChannelFactory and a shared interface. There are many good references on the net on why one is better than the other but personally I prefer to use the ChannelFactory approach as it allows for cleaner separation of concerns and it allows me to share the same interfaces/models on both side of the wire.  Of course this really only works in a closed development scenario, one where you control both sides of the wire.

The issue with using the Channelfactory pattern is that by default it will create synchronous endpoints for use and this is not allowed in Silverlight.  However this problem is easily solved for you and we will take a look at how to solve this.

When you typically setup a WCF OperationContract you typically do something like the following:

[OperationContract]
List<Make> GetMakes();

However as you may have guessed this will create a synchronous method/endpoint when you use the ChanelFactory.  In order to use this in WCF you need to make a slight change to your setup.  You will need to instruct the Contract that you are following the AsyncPattern .  The code below will show you how using the AsyncPattern changes your setup.

[OperationContract(AsyncPattern = true)]
IAsyncResult BeginGetMakes(AsyncCallback callback, object state);
IList<Make> EndGetMakes(IAsyncResult result);

As you can see from above, using the AsyncPattern = true pattern does mean we need to create 2 methods not just 1.  We should take a closer look at these to better understand what is going one.

In the first method we are creating the ‘begin’ call which will return us back a IAsyncResult which will later be provided to the End method.
In the second method we are making a call and passing in the IAsyncResult instance provided to us via the begin call.  It is this second method which will return us back our actual data.

Now that we know how to  create our OperationContract we should take a look at how to create our implementation of these contracts.  The code below will illustrate how to do this

public IAsyncResult BeginGetMakes( AsyncCallback callback, object state )
{
    var db = new AutomobilesEntities();

    var makes = db.Makes.Select( m => new Make {Name = m.Name} ).ToList();

    return new CompletedAsyncResult>(makes);
}

public IList EndGetMakes( IAsyncResult result )
{
    var completedAsyncResult = result as CompletedAsyncResult>;

    return completedAsyncResult != null ? completedAsyncResult.Data : new List();
}

Taking a closer look above you should notice that the Begin method will actually do the ‘heavy’ lifting in terms of performing any real logic.   This method also returns back a AsyncResult class (see below for that class) which will be passed into the ending call The End call.  The End call will accept the provided AsyncResult instance and pull out the data payload inside of it.  It will then pass this payload back as the actual results you were expecting.

Now that we know how to create an Async endpoint how to we spin up an endpoint via the ChannelFactory and make our WCF call work.  Take a look at the code below for that example.

var binding = new BasicHttpBinding(BasicHttpSecurityMode.None)
                              {
                                  MaxBufferSize = 2147483647,
                                  MaxReceivedMessageSize = 2147483647
                              };
            
var endpointAddress = new EndpointAddress(fullEndpointAddress);
var channelFactory = new ChannelFactory(binding, endpointAddress);

var channel = channelFactory.CreateChannel();

AsyncCallback callback = result =>
                                {
                                    var endGetMakes = channel.EndGetMakes(result);

                                    Debug.WriteLine( "I Have Makes" );
                                };

channel.BeginGetMakes(callback, channel);

The magic in the code above which makes this all work is to create the pointer to the AsyncCallback instance and to provide this in your Begin call.

This is the class I used for encapsulating our IAsyncResult

public class CompletedAsyncResult : IAsyncResult
{
    T data;

    public CompletedAsyncResult(T data)
    { this.data = data; }

    public T Data
    { get { return data; } }

    #region IAsyncResult Members

    public object AsyncState
    { get { return (object)data; } }

    public WaitHandle AsyncWaitHandle
    { get { throw new Exception("The method or operation is not implemented."); } }

    public bool CompletedSynchronously
    { get { return true; } }

    public bool IsCompleted
    { get { return true; } }
    #endregion
}

Using the Async Pattern in WCF is a bit more work but it will allow you to do 2 things. 1) Use the Channelfactory in WCF and 2) Create async service calls to allow your application to continue working while you wait for your call to come back.

Till next time,

Filed under: ,
Discuss (1)

Castle Windsor 3.0 is released

Posted by Krzysztof Koźmic, Friday, December 16, 2011 (2,978 views)

Castle Windsor

After successful beta and RC releases final version of Castle Windsor (as well as Castle Core, and a whole set of facilities) has now been released. There are no major changes between final version and RC. The difference is some minor bug fixes, improved exception messages and some small improvements all over the place.

 

The packages are available now, on Nuget (with symbols), and via standard .zip download.

 

Last but not least - thank you to everyone who downloaded beta and release candidate and provided feedback. You guys rock.

Discuss (4)

Entity Framework Error–New Transaction is not allowed because there are other threads running in the session

Posted by Derik Whittaker, Tuesday, December 13, 2011 (1,731 views)

Recently when I was working with Entity Framework inside one of our RIA Services end points I ran into the errors below while trying to save my changes.  Of course at first this error caused me to stop and scratch my head

image

image

To give a bit of background on what I was doing.  Inside one of our RIA calls (Off Topic, not a big fan of RIA but this is not the time or the place) we were doing a bit of background processing.  In this background processing we needed to query the database for some data (as seen below), update the data and then save the data.  However, when I called ObjectContext.SubmitChanges() I would get the error above.  what was really odd was that I was saving on the EXACT same ObjectContext instance as the instance the data was queried from so I was a bit stumped.

Here is the original code which was causing the problems

var socialLinks = ObjectContext.SocialMediaLinks.Where( x => x.ClientID == clientId )

As you can see from the line above the code appears to be pretty harmless.  I am simply reaching into my ObjectContext and grabbing all the items which match for a given client.  Later on in the code I am doing a ForEach loop over the list and changing various values based on rules.  However, it is this code which is causing me errors when I try to save.

After a bit of searching and staring it finally occurred to me what the issue was.  Because I had never actually ‘completed’ my query the original transaction was still opened and when I called save it was trying to create and use another transaction.

To get around this issue (there may be better ways and if so please let me know) I changed my code to be the code you see below.

var socialLinks = ObjectContext.SocialMediaLinks.Where( x => x.ClientID == clientId ).ToList()

By adding the .ToList() to my query I am forcing the fetch to take place at one time, thus closing the underlying transaction to the database.  Now when I saved the data (I literally did not change another line of code) everything worked just fine.

If you find your self in this situation make sure you have actually finished executing your EF queries before you save your changes.  BTW this is done inherently when going across the wire which is why I have never seen this before.

Till next time,

Discuss (0)

Performance Profiling your application is FTW

Posted by Derik Whittaker, Tuesday, December 13, 2011 (1,548 views)

Today one of our production ‘slowness’ issues finally came to a head and it was deemed a TOP priority which meant I actually had a legitimate reason to spend time working on it.  The first think I did to attempt to find the issue was to fire up DotTrace from Jetbrains (killer app and very easy to use) and about 2 minutes later I had found the source of my bottle neck

Take a look at the 2 images below for an illustration of how simple it can be to find and SOLVE very large performance bottlenecks.

This is the original code.  As you can see there are 12 calls (this is inside a loop) to a class called CMEHelperSupportsInstance which in total take up 141 SECONDS.  Just for a bit of background this code is actually making a CORBA call across the wire to a Java server which we integrate with, which means I expect it to be a bit slow, but OMG 141 seconds slow….. GOD HELP ME

image

After making a very simple code change (more on that in a minute) here is the updated logic with perf numbers

image

As you can see from the above we are now only calling CMEHelperSupportsInstance 1 time for a savings of about 134 total seconds. What I found was that we were creating an instance of this class for EVERY iteration of a loop, which as I explained above was VERY expensive.  I moved the creation of this to outside the loop and passed the instance around.  This was a very simple fix but had it not been for the perf tool showing me exactly how expensive.

It is always important to make sure your application is performing as expected but without the right tools and without knowing where to look it is often very hard to find and diagnose where you have performance issues.  If you have an idea of where you have issues and you have a too like DotTrace (or any other .net profiler for that matter) finding and solving issues can be very simple and very rewarding it.

Till next time,

Discuss (1)

Providing Intellisense, Navigation and more for Custom Helpers in ASP.NET MVC

Posted by Hadi Hariri, Wednesday, December 07, 2011 (1,886 views)

 

You probably are aware by now that as of ReSharper 5 we added first-class support for ASP.NET MVC. This included among many things, the ability to provide Intellisense, Create from usage and Navigation to built-in methods such as Controller.View or Html.ActionLink:

 

Navigation

Ctrl+Left Mouse Click or F12 will navigate to the corresponding View

 

image 

 

or to the Action and/or Controller

 

image

Intellisense and Create From Usage

Ability to have Intellisense when providing Actions/Controllers

 

image

 

as well as the possibility of creating from usage

image

 

However, what happens when you want to use a custom function, for instance, a better ActionLink or your own View method? Did you know that you can still get all these goodies? All you need to do is use some Annotations.

Using JetBrains.Annotations

ReSharper uses annotations via the form of .NET attributes to figure out what an ASP.NET MVC View, Action or Controller is. As such, all we need to do for our custom method and extensions to leverage this, is tell ReSharper what parameter corresponds to what.

 

Referencing the annotations

To use ReSharper annotations, we have mainly two options (with a third one hopefully coming soon):

1. We can include the library JetBrains.Annotations.dll in our project and reference it.

2. We can copy the annotations and include it as source in our project

[3. We can use nuget install-package JetBrains.Annotations] Coming soon!

 

The first option is pretty simple. The DLL is located in the ReSharper installation bin folder. For the second option, we open up ReSharper | Options and select Code Annotations entry

 

image

 

select the Copy default implementation to clipboard button and paste into an empty file.

 

Annotating custom methods

Once we’ve completed this step, all we need to do is annotate our parameters with the correct attributes. We’re interested in 3 different attributes in particular:

 

  • AspMvcView which indicates the parameter is a View
  • AspMvcAction which indicates the parameter is an Action
  • AspMvcController which indicates the parameter is a Controller

 

Here is the header corresponding to a base controller with a custom method named ExtendedView

 

image

 

and here’s the header for a custom ActionLink

image 

 

(the body of both methods are omitted and are not necessary to demonstrate the functionality)

 

As soon as we do this, ReSharper picks up these methods and offers us the same functionality that is provided for the methods that ship out of the box:

 

image

 

Notice how we still get Navigation (the underlining), Intellisense and Create from usage in our TheOnlyActionLink custom method. Its much the same for the ExtendedView method

 

image

 

That’s all there is to it.

Filed under: , ,
Discuss (0)

Setting up TeamCity as a native NuGet Server

Posted by Hadi Hariri, Thursday, December 01, 2011 (4,335 views)

 

TeamCity 7.0 EAP (Early Access Program) was recently opened and one of the new features is the built-in support for NuGet. I recently blogged about setting up TeamCity to pack and publish NuGet packages via a plug-in and this plug-in is now included by default in TeamCity 7. However, the real new interesting feature is that TeamCity is now a native NuGet repository too!

Native NuGet Server?

Many of those that have been using NuGet, have most likely been using it to consume packages from nuget.org where there are currently over 3800 unique packages, most of which are open source.

image

 

What happens however if for some reason or another you do not want to submit packages to nuget.org? For instance, think that you want to use NuGet to modularize and distribute code inside your own organization, or create libraries for private consumption. In this case, publishing to nuget.org does not make sense. This leaves you with basically two options:

 

  1. Setup your own NuGet repository by downloading and installing the code that nuget.org for instance
  2. Copy nuget packages to a local share and have everyone read off of that

 

Both of these options come with their own share of overhead. With the local share you now require sharing of folders and permissions. Setting up your own NuGet repository also requires managing permissions and whatnot separately. At the end of the day, its another service to manage.

Fortunately, you now have a third option: TeamCity. The same server that builds your projects, runs your tests, packs and publishes your packages can now also serve them. The best part of it is that it is so simple, that I had to take up the rest of this blog with the previous nonsense just to give it some meat.

Enabling TeamCity as a NuGet Server

I am not going to cover how to pack and publish packages in this post. All that is covered in detail in the previous post I wrote, so please read that first if you’re not familiar with the process. Enabling TeamCity as NuGet and making packages available consists of two steps:

 

1. Enable the server to be a NuGet server

 

Go to Administration | Server Configuration | NuGet tab

 

image

Click on the Enable button to enable it. The same screen with then display two different feeds: a public and a private one:

 

image

If by chance the Public Url is not available, you will probably see a message telling you that you need to enable the Guest account in TeamCity, which can be done from the General tab.

 

2. Make your packages be your Artifacts

Since TeamCity itself is going to be a NuGet server, the step to publish a package is no longer required. However, packing the package is. In this step (NuGet Pack Build Type), we can just configure the output for the package to point to some specific folder, for instance packages

 

image

 

We need instruct TeamCity to ouput the results of this folder as artifacts. This is done in the General Settings step of the Build Configuration

 

image

 

and with that, we’re done. Next up is to configure Visual Studio to consume from this feed.

 

Configuring Visual Studio

Although this step is optional, it is recommended to add your repositories to Visual Studio to avoid having to type long URL’s in each time you want to read from a specific package repository. To do this, click on Options | Library Package Manager | Package Manager Settings

 

image

 

We need to add a new NuGet Repository. I’ve called it Local TeamCity  and the URL corresponds to the public URL provided to me by TeamCity in Step 1:

 

image

 

Notice that I have another entry which is Local TeamCity Auth which corresponds to the authenticated version.

Once we have this, we can now easily consume packages from our repository by merely specifying it in the Package Manager Console, either via the Combobox or explicitly in each call:

 

image

 

 

Summary

That’s all there is to it. By merely publishing our packages as artifacts, TeamCity now provides a full-fledged nuget server which opens up great possibilities when it comes to working and managing dependencies between projects. TeamCity is currently in EAP and much of what I’ve described here is in open to improvements. That is why your feedback is very important. Download 7 and start playing with it today. Let us know what you think.

Filed under: , ,
Discuss (2)

Runtime Exception for PageIndex of a DataPager

Posted by Derik Whittaker, Tuesday, November 29, 2011 (2,693 views)

Today I was building a UI in Silverlight which needed a Data Grid and a Data Pager.  When I setup my pager I had it bound to the various properties that I cared about (Source, PageIndex, PageSize, etc) via my ViewModel.  However when I ran the page for the first time I received the error below

image

At first I was a bit stumped because why in the world would I want to set my Page Index to –1 (as an FYI my Source property is NULL when first bound because of the way we lazy fetch our data.  In order to get around this I did what the error told me and set my Page Index to default to –1. This worked… kinda.  See it worked the first time I loaded the screen when there was NO data loaded in memory.  Every subsequent loading of the page threw another exception telling me that my default Page Index had to be >= 0.

As I sat there scratching my head it dawned on me that the issue was due to the way that the XAML engine reads/parses the elements (left to right, top to bottom).  I reset my default Page Index to 0 and moved my Source property to the left of my PageIndex property and this worked.  Take a look below at my XAML to see the difference.

Original XAML

image

Correct XAML

image

The moral of the story is that you need to pay attention to the order (left to right/top to bottom) of your XAML properties in some places.

Till next time,

Filed under: ,
Discuss (5)
More Posts Next page »