Reuse, Reuse, Reuse – do we need utility libraries? If not, what’s next? Minimods!

We love being productive. And there are tons of generic problems that we solve far too often. The .NET Base Class Library has plenty of functionality (compared to Java w/o Apache.Commons). But still there is much missing.

So, every developer has tons of snippets in his backyard, from where he digs up and copy-pastes class by class, method by method. Then, from time to time, in the name of reuse, we package those utilities in libraries called *.Common or *.Utils, and put them in our toolbox. Some of us (as a species) then publish their util-libraries as open source: Among them Rhino.Commons, Umbrella, Magnum and many more.

The cost of dependencies

The cost of an dependency is high. If you just need that little thing, but introduce a dependency to a big ball of (unrelated) mud – you’re better off copy-pasting exactly what you need. But event that is hard, because if you start writing utilities, then your utilities tend to depend on each other.

Good reads on this topic:

But still…

But still we do not want to reinvent the wheel on every project. So what to do?

Options

Lets just shortly list the options we have for reusing generic code – besides creating huge utility libraries:

  • Copy-paste
  • Creating very specific libraries: but who want’s the overhead of a DLL?
  • … IL-merge those very specific libraries
  • Utilize .NET modules; those are smaller than an assembly and can be linked into any assembly – that is what ILmerge does. But there is no tooling support for .NET modules in Visual Studio…

I think there is just one option left: Single-file distributions with utility-classes, that can be included as source.

But how to distribute them? How to version? How to upgrade?

Then, how to maintain them? Manual download, copy-paste? In times of NPanday and Nuget? Not really.

Minimods

With this in mind I started off something I’ll call Minimod for now. It is a rather small module, containing of source code only, that can be installed into any of your C# assemblies.

I’ll write more on how to create and publish a Minimod later (hopefully in combination with NPanday).

Definition

A Minimod is defined as follos:

  • it must consist of one file and be very specific (no StringExtensionsMinimo, LinqExtensionsMinimod, or MyUtilMinimod please!!)
  • Each Minimod must be in it’s own namespace in order to avoid extension-method conflicts.
  • A Minimod should only depend on .NET BCL or other Minimods

I also want tool-support for integrating it, as well as upgrade/remove.

Proof of Concept

I just started bundling some utilities in classes and created simple Nuget-Packages. This makes it very easy to install and upgrade the files.

image

Then I published those to the Nuget Gallery.

image

When installing, a file will be created in the subdirectory Minimods. I named it *.Generated.cs, because that will prevent ReSharper from complaining about things.

image

Preview of the imported file. Namespace does not fit (see issues).

image

Now we use them:

using Minimod.NestedDictionary;
using Minimod.PrettyText;
using Minimod.PrettyTypeSignatures;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            var width = 22;
            Console.WindowWidth = width;

            var minimods = "Minimods are great! Go get them at Nuget.org, just by searching for 'minimod'.";

            Console.WriteLine(
                minimods
                .ShortenTo(width)
                );

            Console.WriteLine();

            Console.WriteLine(
                minimods
                .WrapAt(width)
                .JoinLines());

            var listPerKey =
                new Dictionary<string, List<string>>();

            Console.WriteLine();

            Console.WriteLine(
                listPerKey.GetType()
                .GetPrettyName()
                .ShortenTo(width));

            listPerKey.EnsureValueFor("key1");
            listPerKey.AddToCollection("key2", "one");
            listPerKey.AddToCollection("key2", "two");

            Console.WriteLine();

            Console.WriteLine("key1: " +
                String.Join(", ", listPerKey["key1"]));

            Console.WriteLine("key2: " +
                String.Join(", ", listPerKey["key2"]));

            Console.ReadKey();
        }
    }
}

The result

image

Still to be considered

  • Namespace should maybe be adjusted to the target-projects namespace + “.Minimods”? Or is it great having *.Minimod for all of them?
  • Id, description and versioning is all done manually now – want to automate this.
  • Haven’t tried with dependencies yet, but that should work.
  • Planning to use NPanday to automate the process of releasing and publishing Minimods ([#NPANDAY-372] Integrate with NuGet and NuGet Gallery (nuget.org))

What do you think? I’d be happy to get Feedback on the process!

I’ll also hopefully keep posting more Minimods.

Current source code is here: moved to minimod/minimods at GitHub (from Braindrops.MiniMods at GitHub)

Advertisements

NPanday 1.3-incubating released under Apache Incubator (Maven + .NET)

UPDATE: 1.3-incubating was removed from our main npanday site again! We forgot to ask the Incubator PMC for a vote, so we had to withdraw the official release.

The direct links provided in this post still work though.

Stay tuned for 1.3.1-incubating to be released soon! This will then be moved to group id ‘org.apache.npanday’ and deployed into Maven Central.

We are pleased to announce our first release of NPanday under Apache Incubator! NPanday moved from Codeplex to Apache Incubator last year.

Don’t mind the “incubator” in the version. NPanday is stable, allthough we hope to move from incubator into a full Apache project as soon as possible.

What is NPanday?

NPanday brings Maven to .NET (and Mono). It offers a set of plugins to build and test projects, and it defines all the necessary packaging types for deploying and resolving .NET artifacts.

Apache Maven comes with a great infrastructure for dependency management, artifact transport, artifact repositories, release flows with scm-integration, and much more. If you don’t know Maven, go read here. Maven is great!

There is also a Visual Studio 2005/2008/2010 Integration for English Visual Studio installations.

Why NPanday, now there is NuGet

Wrong question. Competition is great. Sad though, that at least some of the originators for NuGet didn’t even know about Maven and NPanday.

Maven is an ecosystem grown over almost 10 years. It has much more to offer than auto-download of dependencies. Still I think we need to integrate the dependency-resolving and deployment part with nuget and nuget-gallery (See future plans).

What is new in this release?

NPanday now supports .NET 4.0 and Visual Studio 2010. There has also been major internal improvements. The PAB and UAC directories where removed. Now NPanday uses a clean maven local repository. This also removed the necessity for custom additions to the install and deploy phases – which where duplications of the corresponding maven plugins.

Read the full Release Notes for NPanday 1.3-incubating

What are the future plans?

On short notice we will release 1.3.1-incubating, which already has 9 resolved issues and only one left to be fixed.

At the same time we are working on version 2.0, which is a huge internal change. NPanday uses a internal RDF database where it keeps additional information for artifacts and dependencies. This is obsolete, but lots of work to remove.

We also want to lead NPanday to more .NET-like conventions for directory structures i.e., while still maintaining the Maven-influenced layout.  Of course we also try to improve stability, ease of use and documentation.

My agenda for NPanday:

We are 4-5 active committers from which 2 work full-time on NPanday as of today. We would really like to get more committers involved. Find out on how to develop NPanday in the NPanday Developer’s Guide.

Where do I get it?

You’ll find everything you need here: NPanday – NPanday Overview

Downloads: NPanday – Download

Current Docs: NPanday – Documentation