ROOT.NET.Dynamic 5.34.36.13

Техника

Tuyến Vũ

naxam-blogs

VS Nuget Package Source Manager

This is a rare scenario where I have a library that is not public, but that I’m using in an otherwise public project. I want to use the library, but don’t necessarily want to publish a NuGet package or the source code as part of the repository for broad access.

Further, I want to make sure that if somebody pulls down the repository from Git that they can build the Solution without explicit configuration.

There are a couple of options for this:

  • Use an Assembly Reference with a local Assembly File
  • Use a local NuGet Feed

Part of the ROOT.NET library that allows you to access the C++ ROOT data anlaysis pacakge (http://root.cern.ch/) from .NET languages. Contains libCoreWrapper.dll WrapperPlumbingLibrary.dll, and is only built for this version of root!

This package has no dependencies.

NuGet packages (2)

Showing the top 2 NuGet packages that depend on ROOT.NET.Dynamic:

GitHub repositories

This package is not used by any popular GitHub repositories.

Use vc12 ROOT binaries (VS2013). Deal with shut off of root.cern.ch’s ftp endpoint.

Enables C++ programs to link against ROOT libraries. This package requires that compilers for VS2012 or VS2013 are being installed. Only release mode, multithreaded DLL’s are supported. See the main ROOT website for complete documentation: http://root.cern.ch/

This package has no dependencies.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version 5.34.36 of root. Allow VS2013 use. Switch to https endpoint for downloads

In this tutorial, we’ll cover some basics on how to create a Nuget package. We’ll also look at a way to host your own private Nuget repository. To complete the tutorial, you’ll need to download the NuGet.exe command line utility.

2. Download the .zip sample project here, and unzip it into a subfolder with the name of the Nuget package you wish to create (i.e. \.nuget\NugetDemo\)

3. You’ll see folders here for /content/ and /lib/.

/content/ – any files here simply unzip into the root of the project, so anything you put here will dump as is to the project the package is being added to. You just match the structure you want to have it unpack into and Nuget will unzip it into your package accordingly. The example from #2 uses a ‘Controllers’ and ‘Views’ folder from an sample C# MVC project. The root content folder also contains a web.config.transform. The changes in .config.transform files are added to the matching .config file in the project. In this example, I have an appsettings key I am adding.

/lib/ – contains your binary files you want to include in subfolders based on framework version. In the example from #2, I have a .NET 4.5 (net45) subfolder, and a dll called Utils that I am packaging in. This will be added to my project as a referenced dll when I install the Nuget package. Utils just contains some sample extension methods which are used in the Controller and View from /content/.

/tools/ – (not included, but could be here if necessary) is for powershell scripts you wish to have executed automatically at installation time. I haven’t included any in this sample, but there is plenty of documentation out there on Powershell and what can be done with Nuget packages.

readme.txt – this file is in the root folder and is opened automatically (but not added to the project) when the package is installed.

4. From the root folder (the one with readme.txt) run the command ‘nuget spec MyPackageName’. This will create a file named MyPackageName.nuspec. Note: Be sure Nuget.exe is added to your %PATH% variable as noted earlier

7. Inside Visual Studio, select “Tools > Nuget Package Manager > Package Manager Settings’. Then select “Package Sources” and use the “+” icon to add a new source. Attached is a screenshot of how I have added my own person Nuget repository.

Дополнительно:  Не работает Тачпад на ноутбуке? 5 способов решения TouchPad

personal-repo

8. Now, create a basic C# MVC application. Right click your new web project and select “Manage Nuget Packages”. You see your source on the left rail. Go ahead and add your package you created from step #6. Note that ‘Controllers’ now has an ‘Extensions’ subfolder, ‘Views’ now has an ‘Extensions’ subfolder, Web.config has an AppKey named ‘ExtensionsKey’ and your project has a reference named ‘Utils’ that was not there before. Also, a file called “readme.txt” showed up in your solution explorer although it was not added to your project.

add-nuget-package

9. If you debug/run your application and head to the Url /extensions/strings/ you’ll see that the Extensions controller action ‘Strings’ will execute, leveraging the namespace/dll Utils to present some information. Congrats!

Wrap up

NUGET is the official package manager for .NET libraries, yet it is very powerful. It’s really useful and helpful to deliver your libraries across projects, teams and with the world. Please read it in details here.

Solution 2

  • Share your C: drive
  • Within your Dockerfile, have a dotnet restore --source /packages
  • Use a volume mount to mount your local packages into /packages inside the container: docker build -t webapp4 . -v c:/users/cnaling/.nuget/packages:/packages

Problem

As you might be verify familar with above snapshot: Visual Studio Nuget Package Sources UI, details could be found here. It’s very easy to use, easy to work with. However, if you notice,

  1. It’s system-wide configuration, all configured package sources will be available to your every projects.
  2. It’s machine specific configuration, all of your developers in a project must set up the same to work with packages correctly.
  3. It’s only good for remote based package sources, your packages must be hosted somewhere to be fetched.
  4. It might not work with your CI service

What if you want

  • package sources are configured as per project basis
  • package sources could be located either conventionally on developer machine or on remote server
  • package sources are configured automatically for your project without the developer care
  • package sources must be available for CI service

File Referencing a NuGet Package?

Yesterday I publicly mused that it would be nice to actually be able to use a referenced path in a Nuget Package Reference:

Sure would be nice if you could reference a local NuGet package by its path. Instead I end up with a reference and might have dependency issues.

Something like this below & could even be a Web path.

— Rick Strahl (@RickStrahl) September 11, 2022

In a nutshell, I wouldn’t mind seeing a relative path be able to pull in a NuGet reference from within a package reference in a project:

<ItemGroup>
    <PackageReference Include="../SupportPackages/Westwind.Licensing/WestWind.Licensing.nupkg" />
</ItemGroup>

This seems like a quick and logical way to refernece a NuGet package that doesn’t come from a feed.

I realize all sorts of things can go wrong with this if you hard code a path or that path is just not available. However, for the specific scenario of referencing project relative NuGet packages it seems like a good and somewhat logical approach for a simple and — judging from the comments to my Tweet — common scenario.

Alas, while that specific scenario isn’t supported, it turns out that there are other ways you can achieve this behavior with only a little more extra work by using a local NuGet feed that’s specific to your project/solution. More on that in a minute.

Solution 3

One simpler alternative is to cache the NuGet packages in a separate layer by having them being restored from the csproj project file before copying the source files. Example:

FROM mcr.microsoft.com/dotnet/core/sdk:3.1 AS build-env
WORKDIR /app

# copy csproj and restore as distinct layers
COPY *.csproj ./
RUN dotnet restore

# copy everything else and build
COPY . ./

RUN dotnet publish -c Release -o out

This solution should speed up local development which typically requires quite a few stop -> build -> up cycles.

The main downside is that changing csproj triggers the layer being rebuilt, but this should happen less frequently than rebuilding of the container.

Comments

  • It doesn’t see the path even though it exist on that path.click for image.

    The server I’m using is on a Corporate Network that is why I can’t use dotnet restore, so I’m also experiencing the problem with nuget.org similar to this link.

    For the sample project, I used:

    • the basic .Net Core web app from Visual Studio 2017
    • Docker Enterprise Edition(no UI), Windows container
    • Windows Server 2016 as OS.

    UPDATE 10/15/2018

  • I don’t use docker on Windows. I can’t say the exact steps, but double check if sharing the C: drive is needed explicitly. Googling says some recent versions of Docker EE + Windows 2016 don’t require that step.

Дополнительно:  Что делать, если тачпад не отображается в диспетчере устройств

Summary

I’ll be the first to admit I waste a lot of time trying to find simple solutions like this, because I simply don’t know about them. The MS Build process has so many components to it, and Microsoft has done a good job of extracting the most common features and defaulting them where everything ‘just works’ out of the box which is awesome (Kudos!). But when you end up doing a little bit different it’s often really hard to discover the customizations that are available. This feature I describe here is great, but judging from responses to my Tweet few know about it. Hopefully a post like this helps out in discovery and taking advantage of this functionality a little bit more easily.

The ability to add a local Nuget.config to a solution or use <RestoreAdditionalProjectSources> in a project to override behavior are great tools to add a private NuGet feed that is pre-configured and doesn’t required consumers of the project to fiddle with setting up a custom package source.

Using a Solution or Project Local NuGet Source

So you can also use a local NuGet Source. I’ve always known that you can add a local NuGet package source, but in the past I’ve shied away from this solution because I thought — incorrectly — that would mean consumers of a repository would have to explicitly set up the secondary package source. Turns out that’s not correct and you can pre-configure a package source as part of your Solution.

Additional Package Sources can be set in a number of places:

Global Package Source

The global package source lives in %appdata%\nuget\nuget.config and looks like this:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <packageSources>
    <add key="NuGet Package Source" value="https://api.nuget.org/v3/index.json" />
    <add key="Microsoft Visual Studio Offline Packages" value="C:\Program Files (x86)\Microsoft SDKs\NuGetPackages\" />
    <add key="Local NuGet" value="c:\projects\nuget" />
  </packageSources>
  <apikeys>
    ...
  </apikeys>
</configuration>

This configuration is set when you make changes to your package source configuration in most IDE tools like Visual Studio, Rider, OmniSharp etc.

Solution Local Package Source

But you can also override this global nuget.config file with a local nuget.config in your local Solution Root folder. So to override or add additional package sources I can create a local file, add it to the Solution Root Folder and then add a package source like this:

<configuration>
  <packageSources>
    <!-- package source is additive -->
    <add key="Westwind.WebStore Local" value="./SupportPackages" />
  </packageSources>
</configuration>

I can now add any local packages into the SupportPackages folder and it will now be found on build.

Here’s what this looks like:

And here’s the local folder setup:

While this is not as easy as a relative path package reference as per my original musing, it’s still a pretty simple solution. As a bonus it works for many packages and doesn’t require for projects to use any path references, so it’s actually a cleaner solution.

Project Specific PackageSource

Another even easier way to add a package source at the project level is to use <RestoreAdditionalProjectSources> in an individual .NET project, right inside of your project file.

So in my Westwind.Webstore.Business project I can now reference a project relative path:

<PropertyGroup>
    <TargetFramework>net6.0</TargetFramework>
    <Version>0.1.2</Version>
    <RestoreAdditionalProjectSources>./_SupportPackages</RestoreAdditionalProjectSources>
</PropertyGroup>

which keeps the extra NuGet package tied to the project rather than the solution. I can of course still point back to the solution folder as well, but the real value of this option is that I can keep the NuGet reference with my specific project that needs it, keeping the dependency management confined to the project that needs it, rather than pushing it up to the Solution. This makes this approach portable even if the project is attached to another solution later.

Дополнительно:  Mounting dev on root dev failed invalid argument

Here’s what this looks like in my project:

Solution

It’s provided out-of-the-box by Microsoft, you just need to create a nuget.config file located in your project root folder with all package sources required by your project. This snippet is an example of how you could do it.

In line 4, it specifies that there are packages for the current project located inside folder nugets within current folder.

In line 5, it specifies the package source from Syncfusion.

You could create/edit this configuration file manually with either a text editor of choice or through Nuget CLI as details here.

Solution 1

To have all packages ready you need restore before building.
To have all packages during the build you need to copy the packages.

Here is an example in form of an experiment:

Have the sdk ready: docker pull microsoft/dotnet:2.2-sdk.

Have src/src.csproj ready:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>netstandard2.0</TargetFramework>
  </PropertyGroup>
  <ItemGroup>
    <PackageReference Include="Newtonsoft.Json" Version="12.0.2" />
  </ItemGroup>
</Project>

Have src/Dockerfile ready:

FROM microsoft/dotnet:2.2-sdk AS byse
COPY packages /root/.nuget/packages
COPY src src
RUN ls /root/.nuget/packages
WORKDIR /src
RUN dotnet restore
RUN ls /root/.nuget/packages

Restore the Packages:

docker run --rm -v $(pwd)/src:/src -v $(pwd)/packages:/root/.nuget/packages -w /src  microsoft/dotnet:2.2-sdk dotnet restore

Build the Image:

docker build -t test -f src/Dockerfile .
Sending build context to Docker daemon  13.77MB
Step 1/7 : FROM microsoft/dotnet:2.2-sdk AS byse
 ---> e4747ec2aaff
Step 2/7 : COPY packages /root/.nuget/packages
 ---> 76c3e9869bb4
Step 3/7 : COPY src src
 ---> f0d3f8d9af0a
Step 4/7 : RUN ls /root/.nuget/packages
 ---> Running in 8323a9ba8cc6
newtonsoft.json
Removing intermediate container 8323a9ba8cc6
 ---> d90056004474
Step 5/7 : WORKDIR /src
 ---> Running in f879d52f81a7
Removing intermediate container f879d52f81a7
 ---> 4020c789c338
Step 6/7 : RUN dotnet restore
 ---> Running in ab62a031ce8a
  Restore completed in 44.28 ms for /src/src.csproj.
Removing intermediate container ab62a031ce8a
 ---> 2cd0c01fc25d
Step 7/7 : RUN ls /root/.nuget/packages
 ---> Running in 1ab3310e2f4c
newtonsoft.json
Removing intermediate container 1ab3310e2f4c
 ---> 977e59f0eb10
Successfully built 977e59f0eb10
Successfully tagged test:latest

Note that the ls steps are cached and would not print on a subsequent call. Run docker rmi test to reset.

Step 4/7 runs before the restore and the packages are already cached.

Step 4/7 : RUN ls /root/.nuget/packages
 ---> Running in 8323a9ba8cc6
newtonsoft.json

This can solves excessive restore times for example during automated builds.

To solve your network issue you can try to mount the network patch instead of the local path during the resolve step or robocopy files from your corp network into a local cache first.

Using a Library Assembly Reference

In the past I’ve always used local assembly references for this scenario. Although it’s kind of downplayed in .NET Core in favor of NuGet packages, you can still reference assemblies in Core projects.

You can use the <Reference> element in a project file and hard reference a .dll file to pull in an assembly reference.

To do this:

  • Create a folder inside of the project/solution
  • Copy the assembly or build output folder into that folder
  • From projects that need it, add an assembly reference to the DLL

Here’s what that looks like in a referencing project:

<ItemGroup>
    <Reference include="../SupportAssemblies/Westwind.Licensing/Westwind.Licensing.dll" />
<ItemGroup>

where ../SupportAssemblies/Westwind.Licensing/ contains the full build output of from the Westwind.Licensing project. In this case it’s just a single assembly with no dependencies, but if there were direct dependencies they would also show up in that folder and are required to resolve the dependencies when the assembly is loaded from this reference.

This works, and I’ve been using this approach for ages all the way back to .NET 1.x. But in this age of NuGet packages that can reference other dependencies more easily it seems a bit quaint 😄. There are also potential complications when it comes to resolving dependencies especially these days when most libraries have other NuGet dependencies which can’t be automatically resolved by an Assembly Reference unless the dependencies are explicitly output and copied into the library folder.

So while direct assembly referencing still works, NuGet referencing would be a better choice if it can be made self-contained.

Adding Local References and Packages to a Project

As mentioned there are a couple of ways you can pull private code into a project by using:

  • A local Assembly Reference
  • Using a private or local NuGet Feed
Оцените статью
Master Hi-technology
Добавить комментарий