NuGet (Anti-)Patterns - Tales from the Trenches

NuGet (Anti-)Patterns - Tales from the Trenches

Many organizations trying to onboard NuGet are expecting to experience a fast transition from dependency hell towards a structured and organized NuGet package repository. Whilst some succeed with ease, others don't know where to start and fail miserably.

This session aims to raise awareness around some NuGet (anti-)patterns and practices. Whether you're working on open source projects or in an enterprise environment, or both, this session might help you saving some time and headaches regarding package creation, versioning and publication, as well as repository organization and automated builds. 

946ee540fb9ff876905c6d3d25db0ac7?s=128

Xavier Decoster

June 20, 2013
Tweet

Transcript

  1. #comdaybe NuGet (Anti-)Patterns: Tales from the Trenches Xavier Decoster

  2. Who am I? Xavier Decoster Founder of MyGet.org NuGet contributor

    Author of Pro NuGet MEET member http://www.xavierdecoster.com @xavierdecoster
  3. In this session

  4. Agenda • What is NuGet (not) • Package versioning •

    Package repositories • Lessons learned
  5. What is NuGet? • Solution-level Package Management for .NET •

    Tools: – NuGet.Core – NuGet.exe – NuGet Gallery (nuget.org) – NuGet-Based Microsoft Package Manager • Your new search engine!
  6. What is NuGet not? • Perfect • Tool that magically

    fixes all your problems • Replacement for software installers
  7. Package versioning A single dot can separate heaven from hell…

  8. #1 – Semantic Versioning Major Breaking changes Minor Backwards compatible

    API additions/changes Patch Bugfixes not affecting the API Prerelease Alpha, Beta, …, RC1, RC2, … Build Time stamp, VCS metadata, … 1 . 0 . 2 - alpha + 2013.06.20.143010 Read the full specification at http://semver.org/ Major Breaking changes Minor Backwards compatible API additions/changes Patch Bugfixes not affecting the API Prerelease Alpha, Beta, …, RC1, RC2, … Build Time stamp, VCS metadata, … Major Breaking changes Minor Backwards compatible API additions/changes Patch Bugfixes not affecting the API Prerelease Alpha, Beta, …, RC1, RC2, … Build Time stamp, VCS metadata, … Major Breaking changes Minor Backwards compatible API additions/changes Patch Bugfixes not affecting the API Prerelease Alpha, Beta, …, RC1, RC2, … Build Time stamp, VCS metadata, … Major Breaking changes Minor Backwards compatible API additions/changes Patch Bugfixes not affecting the API Prerelease Alpha, Beta, …, RC1, RC2, … Build Time stamp, VCS metadata, … Major Breaking changes Minor Backwards compatible API additions/changes Patch Bugfixes not affecting the API Prerelease Alpha, Beta, …, RC1, RC2, … Build Time stamp, VCS metadata, …
  9. #1 – Semantic Versioning • NuGet versioning algorithm differs from

    SemVer SemVer NuGet v x SemVer Versioning Scheme major.minor.patch[-prerelease][+build] v v NuGet pre-release package major.minor.patch-prerelease v v NuGet release package major.minor.patch x v MSDN Versioning Scheme major.minor.build.revision[-prerelease]
  10. #2 – Avoid 3-dots versioning schemes • Even though supported

    by NuGet – Not supported in SemVer – Not supported in combination with pre- release tag in patch… ergh.. build number • Instead use 2-Dots SemVer notation • Optionally with pre-release tag
  11. #3 – Maintain a smooth upgrade path • Don’t change

    Package ID along the way! –Your packages will get stuck –So will your consumers
  12. #3 – Maintain a smooth upgrade path • Version Precedence

    – 1.0.1-alpha00001 < 1.0.1-alpha00256 < 1.0.1-alpha < 1.0.1 – Question: Where does 1.0.1-alpha2 fit? MyGet.Core 1.0.1-alpha00001 MyGet.Core 1.0.1-alpha MyGet.Core 1.0.1 MyGet.Core 1.0.1-alpha00256 …
  13. #4 – The effects of tight coupling… • Small packages

    > large packages • Specific functionality > Multifunctional packages
  14. Package repositories As important as your VCS!

  15. #5 – Package Restore • A package repository is for

    … packages – What’s a source repository for? • Impact of package restore – No more duplication of binaries – Less merge conflicts (no binary diff) – Maintain overview of consumed packages in single place – Less network I/O (NuGet cache) – Package source is now critical system (as is your source repository…) • Contra-argument: single point of failure – Good remark: now deal with it! – What if I’m disconnected from the package source(s)?
  16. #6 – Split package repositories • Don’t pollute consumers’ repository

    with your internal DEV builds – MyGet.org is great at this: set up as many feeds as you want and promote packages from one to another (including nuget.org!) MyGet.Core 1.0.1-alpha00001 MyGet.Core 1.0.1-alpha MyGet.Core 1.0.1 MyGet.Core 1.0.1-alpha00256 … Different levels of support Different audience Different versioning scheme Different SLA? MyGet.Core 1.0.1-alpha00001 MyGet.Core 1.0.1-alpha MyGet.Core 1.0.1 MyGet.Core 1.0.1-alpha00256 …
  17. #7 – Once published, don’t delete packages • Breaks package

    restore! • Forces consumers to upgrade! • Using own NuGet server or file share? – Remove user permissions to delete! • Maintains upgrade path • Still available through package restore • Supported by NuGet.org and MyGet.org “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” - Rob Reynolds, creator of Chocolatey.org
  18. #8 – Have a fallback repository • Backup consumed packages

    –Mirror them on MyGet.org –Download them • Especially when using Package Restore –From NuGet.org –From any external feed • Each consumer has local cache (incl. the build server!) –%LocalAppData%\NuGet\Cache
  19. Lessons learned General guidance & advise from the trenches…

  20. #9 – Spot Binding Redirects • Mitigates potential risk for

    conflicts – During assembly resolution • Investigate why – Package versions not aligned? <configuration> <runtime> <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> <dependentAssembly> <assemblyIdentity name="myAssembly" publicKeyToken="32ab4ba45e0a69a1" culture="neutral" /> <bindingRedirect oldVersion="1.0.0.0" newVersion="2.0.0.0"/> </dependentAssembly> </assemblyBinding> </runtime> </configuration>
  21. #10 – Use Sample Package or Readme.txt • Don’t pollute

    your actual packages • Provide a readme.txt – If you can’t automate the manual instructions – If you want to have your consumers read some specific info – Automatically presented to consumer during installation • Use a sample package when appropriate – Separate package  Different package ID – Convention: {packageID}.Sample • SignalR  SignalR.Sample – Sample package depends on actual package you want to ship
  22. #11 – Uninstall Should Leave No Traces • Obvious, but

    often neglected/forgotten – Be a good citizen • Uninstall reverses installation + any side-effects – Unless modifications happened • Uninstall – Any files copied (binaries, sources, content, scripts…) – Tools package: any system modifications (PowerShell modules, registry keys, environment variables…)
  23. demo Package sources, feeds, packages and their versions playing along…

    Package Promotion
  24. Q&A

  25. Thanks! http://www.xavierdecoster.com @xavierdecoster Come get your MyGet stickers, you might

    get lucky! 