Rory Primrose

Learn from my mistakes, you don't have time to make them yourself

View project on GitHub

Filtering items in the MSF 2.0

I’ve been playing with the MSF over the last couple of years. For too long I have been dabbling in a services based project that synchronises data between a set of clients. The system has been through several designs starting with hand-crafted change tracking which was really tricky. The next version used MSF on the client manage this process. This didn’t have the best result as there was no central replica for the data held by the service. The third design used a proxy provider so that central metadata information was held by the service. The fourth and latest design completely pushes MSF into the service.

The latest design allows clients to simply work with services and not have to have any understanding of MSF. There are a few hurdles with this design however. The provider implementation on the server needs to implement a preview sync so it can tell the client what changes needs to happen without doing them at that time. When a change does happens, the client will only action a single change at a time each of which must operate within a sync session in the service. This means that the sync provider also needs to work with a filtered sync session.

Read More

What is the working directory for Windows services?

I’ve been developing a windows NT service for the last week and I hit an interesting issue today. The configuration for the service contains a relative path which is used in the construction of a class. When this constructor is called, the code checks if the directory exists and creates it if it doesn’t.

The service in question logged errors indicating that there were insufficient privileges for creating the directory. This told me two things. Firstly the directory didn’t exist and secondly there is a permissions problem. I verified that the directory was created by the installer so that means that there is an issue with relative paths.

I quickly realised that the current working directory of a Windows service is probably not the path of the service assembly. Most likely the current directory for a Windows service is C:\Windows\System32. This meant that any work with relative paths was likely to cause grief.

Read More

Is there a point to code coverage?

Code coverage is a concept that is often misunderstood and misused. It gets some criticism every once in a while because of this.

The most common misconception is that code coverage is a measure of code quality. The name code “coverage” also makes it easy to assume that it is a metric regarding the exhaustiveness of test effort. Neither of these are incorrect.

My definition is that code coverage is a measure of what you haven’t tested. Nothing more, nothing less.

Just because something is covered by a test does not ensure that the code is either of adequate quality nor that all possible scenarios are tested for that code. If it isn’t covered though then it isn’t tested and needs some attention.

Read More

Using testrunconfig sometimes fails to deploy dependencies

I’ve never been a fan of deploying test dependencies using testrunconfig. I prefer dependencies to be located as closely as possible to where they are used, ideally on an individual unit test. Using testrunconfig means that the dependencies are deploy at the solution level.

Having dependencies attached to each unit test for my current project has become unmaintainable however as almost all unit tests require the same dependencies. This makes testrunconfig appropriate in this case.

The issue I found with deploying dependencies with testrunconfig is that the dependency is not deployed into the TestResults directory when a new dependency reference is added to the config. This appears to be a bug in Visual Studio where the testrunconfig contents is cached. The workaround is to reload the solution. Each time this happens I have actually closed the IDE and opened the solution again. When the test run is executed the dependencies are not deployed as expected.

Read More

Changing a TFS bound solution namespace

Changing the namespace of a solution that has already progressed significantly down the development path can be a pain. Visual Studio doesn’t native support namespace refactoring and tools like R# can get bogged down with a huge set of changes. There is usually a dirty result if either of these tools are used as the project and solution directories are not renamed. These need to be done manually in Source Code Explorer which then throws out the relative paths stored in the solution file.

Changing a namespace can be a messy job. In these circumstances it’s often best to hand craft an external solution to this problem. I’ve finally written that solution as a console app after doing this job the painful manual way too many times.

The attached file contains the console application code. There is no defensive code against exceptions so it’s best to run this in the IDE. There are three constants you need to update before running this. These are the root path, find text and replace text. The code records everything that happens out to the console and a log file that is unique for each run.

Program.cs (11.54 kb)

Read More

ThreadStatic gotcha with ASP.Net

I had a requirement recently in a service implementation that business rules at any point throughout the execution of a service request could determine a message to return in the header of the response. Because these circumstances don’t affect the execution of the request (no exception is thrown), I needed a loosely coupled way of recording all the required messages and handling them higher up the stack.

Storing data against the executing thread was the obvious solution. I considered manually storing information in the context data of the thread, but then thought this would be a great opportunity to use the ThreadStaticAttribute. I coded this up and it all seemed to work well.

Read More

DisconnectedContext when debugging with MSTest

I have been hitting a DisconnectedContext issue when I’ve been running MSTest in the Visual Studio IDE with the debugger attached. At first I thought it was an issue with debugging WF, but it is now also happening with LINQ to SQL.image

The debugging on the thread of the executing test appears to be stopped when this is hit. Other threads/tests in the test run will still hit breakpoints however.

Searching the net hasn’t yielded any pointers. Anyone out there have some information about this?

Read More

Sense of satisfaction

I just found out that something I came up with a few years ago in another job has hit production and is making a big difference. There were a lot of people involved in supporting the idea and some innovators who took the concept and applied it in ways I didn’t think of. Overall it is a great result and I’m very happy to see such a change being applied.seal

Read More

Quick tip for undoing unchanged TFS checkouts

Reviewing changesets with a large number of files that haven’t changed can be a significant waste of time. Sliming changesets down to only changed files is a great idea before checking in files.

I have previously been doing this manually which in itself is time consuming. Fortunately the TFS power toys package comes with a handy utility to automatically uncheck out any files that haven’t changed. Running TFPT.exe uu /r will do the trick. Running up an instance of the Visual Studio command prompt and entering in this command can also be a hassle. Thankfully Visual Studio makes this easy with the support for external tools.

Read More

Custom fields support with SqlMetadataStore in the sync framework

I am putting together a sync framework provider and have come across some issues that do not appear to be documented. I’m adding custom fields to the item metadata so that I can store additional information for items that are synchronised with another provider. To do this, you define the custom fields for items as part of initializing the metadata store. The tricky thing is that it isn’t clear what data types are supported and how to correctly use the data types that are supported.

I have the following initialization code.

Read More