If you aren’t aware, Kraken is my personal class library that I’ve been using since the early days of .NET. It has evolved over the years to support new featuers as .NET and my needs have changed. The entire source code is available on Github and I have recently been pushing builds to NuGet. Prior to that I ran my own private NuGet server where I hosted the packages and used them in my projects. Now that .NET Standard 2.0 is out and my company is looking at moving to .NET Core it is time for me to upgrade Kraken to .NET Standard. I’m going to document that process here because I think my upgrade path is going to be very similar for others.
Migrating to SDK Project Format
If you are not aware yet Visual Studio 2017 shipped with support for a newer project format (informally known as the SDK project format). The newer format came about for a variety of reasons including:
- The traditional project format is very verbose.
- The traditional project format is hard to read and edit.
- The traditional project format requires the file to be modified for every change made to the project.
- The .NET Core
project.jsonformat did not easily map to the traditional project format.
While the focus on the new format has been to support .NET Core applications it can be used with many other project types as well, with restrictions discussed later. In this article I will discuss how to migrate a traditional project file to the newer SDK format. There are numerous other blogs on this same topic if you want to get different viewpoints.
Creating an SSIS Custom Task, Part 2
In the last article we created a simple SSIS package to generate an SSRS report and save it to disk. For a single report this is fine as it didn’t require a lot of code but imagine if we wanted to write new packages and reuse this code. This is where script tasks break down. Each script task is a standalone block of code, basically its own .NET project. Code in one script task has no access to any other script, even in the same package. The only way to share code is copy/paste. This is error prone and unmaintainable.
One way to work around this is to create code outside the script task and copy paste the source files into each script task. This works but can be difficult to maintain over time. The ideal solution is to move this code into its own assembly and then reference the assembly in each script. Unfortunately SSIS requires that all script references be in the GAC. This complicates deployment as we’ll see later but is doable.
This is where SSIS custom tasks become useful. When you want to use the same script task in several different places or packages then it is time to promote it to a custom task. This provides several benefits.
- Code duplication is eliminated.
- The need for a script task goes away and is replaced by a reusable task.
- A custom task is easier to use in packages then script tasks.
- The custom task can access functionality that is difficult or impossible to do inside a script task.
For this article we will replace the existing script task to generate SSRS reports with a custom task. Creating the task and building the UI is straightforward once you get past the initial learning curve. Surprisingly though working with Winforms proves to be the most challenging aspect of the process. Before continuing be sure that everything is setup as discussed in the previous article.
Documenting Web APIs with Swagger
A while back I posted an article on how to extend the existing help pages generated by Visual Studio for Web API projects to use reflection instead of XML documentation. One of the limitations of that approach was that you could not test the APIs directly. You had to use SoapUI or equivalent. Since then I have started using Swagger for documentation. As a documentation/testing tool it fills the need. In this article I will demonstrate how to integrate Swagger into a Web API project. Additionally I will continue to use the reflection provider from the previous article.
Fluent Argument Validation
Quick, what is the syntax for ArgumentException? How about ArgumentOutOfRangeException? Did you know the arguments are swapped between the two? In one case the parameter name comes first while the other has the message first. Getting this wrong is so easy that it happens a lot.
Windows Services Made Simpler, Part 3
In this series of articles I have been demonstrating a simple approach to making Windows services. In the previous article I discussed the different components generally involved in writing a service. I also provided the code for the service host and started working on the service instance. In this article I’m going to finish up the implementation of the service and demonstrate how all this comes together.
Windows Services Made Simpler, Part 2
In the last article I provided an overview of Windows services and the issues involved in writing one compared to a normal program. In this article I will demonstrate how to write a simple service in a way that helps alleviate these issues. Before getting into the code for a service it is important to reiterate that a single process can host multiple services at the same time and each service can be started or stopped on its own. It is therefore useful to break up a service into its components so that each component does only what it is expected to do. When creating a service I find that there are 3 different components: service host, service instance(s), and service worker.
Windows Services Made Simpler, Part 1
In Windows a service is a process whose lifetime is managed by the system rather than by a user. MSDN describes a service as a long running process and often times this is true. Services tend to start before a user logs in (or shortly thereafter) and run until the system shuts down. This is unlike traditional applications that start up after a user logs in and terminates when they log out. While a service looks a lot like a standard application they behave quite a bit differently. In this article I’ll discuss some of the issues around creating a service and ways to make it easier to write and debug one.
Adding Dates to C#
UPDATE: A bug was recently found when determining the difference between 2 dates across a year boundary. A corrected version has been uploaded to the site.
In .NET the DateTime type represents both a date and a time. .NET doesn’t really have a pure date type. Ironically it does have a pure time type in the form of TimeSpan. In general this isn’t an issue but when you really just need a date (i.e. the end of a grading period) then you have to be aware of the time. For example when comparing 2 date/time values the time is included in the comparison even if it does not matter. To eliminate time from the comparison you would need to set both to the same value (i.e. 00:00:00). Another example is conversion to a string. A date/time value will include the time so you have to use a format string to eliminate it. Yet another issue is that creating specific dates using
DateTime isn’t exactly readable (i.e. July 4th, 2000 is
new DateTime(2000, 4, 4)).
Language Friendly Type Names
.NET uses Type everywhere to represent type information.Not surprisingly Type is language-agnostic. In many cases it is useful to get the friendly (aka language-specific) name for a Type object. .NET does not provide this easily. There are several different approaches but none of them work really well if you want the name that would have been used in your favorite language. This post will discuss some of the options available and then provide a more general solution to the problem that doesn’t actually require much effort.