Rick Strahl's Weblog  

Wind, waves, code and everything in between...
.NET • C# • Markdown • WPF • All Things Web
Contact   •   Articles   •   Products   •   Support   •   Advertise
Sponsored by:
West Wind WebSurge - Rest Client and Http Load Testing for Windows

How to manage Content in NuGet Packages?


:P
On this page:

As many of you have probably noticed I’ve been preoccupied the rewrite/repackaging of my Westwind.Globalization library of late and I’m trying to make this library more approachable and easier to get started with. One thing I’ve been struggling with over this beta period is how to best lay out the NuGet packages to make the library as easy as possible to use and get started with while also making it reasonably maintainable.

One of the things to make it easier to get started has been to provide some ‘starter’ content as part of the NuGet package. That is provide a sample page along with a small set set of sample resources that can be imported and let new users both test whether resource loading from the database is working as well as letting her play and see the localized data actually working with the ability to make changes and see the changes reflected in the running application immediately.

You may have noticed the question mark in this post – this means that I’m especially looking for some insights, discussion and ideas how to best approach how to break out the packages  for this library. I have a plan and I’ll talk about it, but it’s not set in stone so if you have any insight or suggestions I would love to hear about it in the comments.

West Wind Globalization current Package Layout

To set the stage here let me describe the current package layout of Westwind.Globalization. Currently there are two NuGet packages:

  • Westwind.Globalization
    This is the core package that contains the custom database .NET ResourceManager, the core Database access manager API that deals with serving ResourceSets as well as providing the resource editing and management functionality. There are also libraries for importing and exporting Resx resources and creating strongly types classes etc. In essence it’s all the core, non-Web functionality that can work in any type of .NET project including MVC and Web API projects that don’t use the Web Resource Editor.
  • Westwind.Globalization.Web
    This is the ASP.NET Web specific package that contains two separate ASP.NET ResourceProviders, support for the localization administration Web Resource Editor, as well as some WebForms specific features to support meta:resourcekey bindings and a design time resource provider. This package currently also includes the above mentioned sample page and Resx resource files that can be imported into the resource editor.

Take 1 – Include the Data in one of the main NuGet Packages

I’m pretty sure the current package layout is not going to last.The ‘core’ package is fine – it contains only an assembly with the core functionality that will work in any project. If you’re using a non-Web project, or an MVC project where no ASP.NET resource Provider is used and you don’t need the Web Resource Editor the Core package alone works. Clean, simple, minimal and no fuss.

The Web package is the problem child. It’s the one that adds all this ‘additional’ content. Specifically if you look at the package layout I have this:

NuGetPackage

IOW – that’s a lot of ‘extra’ content for a NuGet package.

Pros:

For new projects and getting started it’s obviously very nice to have everything in one package – you install one package and everything you need is there. There’s no searching around trying to find the ‘right’ package, it’s just there.

Cons:

There’s a lot of ‘clutter’ obviously. A lot of stuff gets added to your project – a lot of stuff that you probably will have to remove after you’ve done your initial installation. But even worse with the package layout like this if you delete say all the sample content, and then later do a NuGet Update-Package all that content is restored right back into your project.

Take 2 – A Starter Package

My current thinking is to create a third package – a Westwind.Globalization.Web.Starter package that contains only the sample content. The idea is that you would typically install the starter package into Web projects once, then remove the Westwind.Globalization.Web.Starter package from packages.config and then never see the sample content again during updates or reinstalls. Developers that have used the library before then also don’t have to deal with the extra content as they can just install the raw .Web package.

Note that I would still leave in the LocalizationAdmin interface which is essentially a self contained Web application. I consider it an integral part of the Westwind.Globalization.Web library and I think it belongs into a new project (more on this below). Since the package is geared to be placed into a Web I expect that most if not all people using the library will be using the Web Resource Editor so I think that’s a fair assumption.

Pros:

Allows for cleaner updates (once the starter package is removed). Developers who are experienced don’t have to install the starter package and don’t have to clean up their projects.

Cons:

I have to make sure that I steer new users to the Starter package and explain that they can remove the starter package from packages.config (can’t do this from the NuGet browser as that would uninstall the dependencies as well). Extra maintenance overhead for the extra package as you want to keep the version numbers in sync (even if nothing changes in the content of the package.

Moar???

This is where I’m curious for feedback :-) How do you manage NuGet packages that hold a lot of content? What would you like to see as a consumer of NuGet packages which is probably the most important point.

There’s a fine line between not enough abstraction and too much clutter.

Should this library be broken up into even more packages? Break out the WebResourceEditor as a separate package so all content is sparated out completely from the .Web package? Or does that just create a NuGet package hell?Personally I have to say I’m not a huge fan of libraries with a ton of NuGet references. You know the ones where you do a search for the library in the NuGet browser and you find two pages worth of libraries that pop up with no clear idea which one to load. Ok this isn’t that bad, but you get the idea. It’s nice to have just one thing to install, but there are trade offs obviously. I personally am not a fan of NuGet packages that I install where 5 other packages are pulled in where you often don’t have any idea exactly what they do and what dependencies they have.

For me there’s also the matter of maintaining a bunch of NuGet packages. Making a change to packages up the chain often requires that you rebuild them to ensure the latest versions of packages are loaded for the dependencies (because of NuGet’s inability for options to automatically pick the highest version which sucks).

NuGet really isn’t well suited for content because it does a terrible job of letting you put in content only once and once the content is there does a terrible job updating stuff (some stuff gets updated other stuff is left alone because it has changed – which can be very unpredictable with the only reliable way to update content being deleting the content then updating).

I appreciate any input for discussion…


The Voices of Reason


 

Stephen Cleary
May 29, 2015

# re: How to manage Content in NuGet Packages?

I agree that NuGet is quite poor at handling content. Sample content in particular, which you generally do not want staying in the solution.

Personally, I'd prefer having starter/sample content distributed completely differently. Like its own GitHub project. Or, for simpler libraries, LINQpad samples (which can be included in NuGet packages without affecting the project).

But if you prefer NuGet distribution, I'd recommend at least putting in a readme.txt (automatically displayed) explaining that the consumer should probably remove that package. On a side note, I believe the NuGet GUI will allow you to remove the package without its dependencies - you just have to answer the dialog correctly. :/

Rick Strahl
May 29, 2015

# re: How to manage Content in NuGet Packages?

@Stephen - Normally I would agree with distributing sample content separately, but in this case the 'sample' content is actually a reality check that makes it easy to see that the provider is working as well as allowing some playing around with some localized data to see it all work.

External samples/starters are fine if things are more optional, but in this case I don't think anybody would actually go and load the samples from say GitHub. So I think a starter package is probably the way to do this best.

Paul Wheeler
May 29, 2015

# re: How to manage Content in NuGet Packages?

I think your approach makes sense, and seems to put each project at a reasonable size and scope. I've personally used a number of github sample projects in the past, but I think having a starter nuget would work just fine. There's nothing stopping someone from just adding the starter to a new visual studio project to play around with if they don't want to clutter their actual project and get the same result as the github sample.

Rick Strahl
May 29, 2015

# re: How to manage Content in NuGet Packages?

Yup - I've updated the packages now and there's a .Starter project. We'll see what the feedback is. Biggest piece of this was updating the various documentation places where the packages are mentioned :-)

Miguel Alho
June 02, 2015

# re: How to manage Content in NuGet Packages?

One thing that worries me is that package references are still (or at least for now they still are) a version-per-project. You can still have N different versions of the same package in the solution, which considering version binding can be really problematic. The vNext configs don't seem to have binding redirects (which could actually be a good thing). Not sure how Rosyln resolves this (still need to test it) but in .NET 4.5, multiple versions of the same DLL is a very painfull thing to resolve...

A global -solution level version would be nice.

I do like the modular concept, and more granular packages is actually something I find interesting, but the tooling around will need to support it well. Anyone working on a large modular project is gonna have a lot of trouble if it isn't fast. (been there... it REALLY is painful to deal with...)

Harry McIntyre
June 10, 2015

# re: How to manage Content in NuGet Packages?

I've got a project (FormFactory) which has customizable js/css/cshtml templates. What I did was to mark the files as EmbeddedResources and include in the core library dll. I have a second {projectname}.Templates package which can be optionally installed. If the user just wants to avoid clutter then they can use my EmbeddedResourceVirtualPathProvider package. This will load files from the assembly, unless the file is present on disk i.e. they have installed the Templates package;

Andras Zoltan
September 08, 2015

# re: How to manage Content in NuGet Packages?

Very curious Rick:

What are you going to do now that, as of 3.1, Nuget doesn't support content any more?

I've used Nuget content extensively in the past to distribute 'bootstrapping' files; startup code with partial hooks, Razor code, View/Controller templates etc, and clearly we won't be able to do it like this any more.

I'm guessing it's going to be Bower?

West Wind  © Rick Strahl, West Wind Technologies, 2005 - 2024