Nuget xdt transform does not work for config files - nuget

I have .NetStandard library. I'm going to use it in .NetFramework and .NetCoreApp applications.
It uses System.Configuration.ConfigurationManager package for work with config files. I need to transform these config files during my library installation.
I found 2 ways:
tools folder in nuget package with install.ps1 file in it
content folder with app.config.install.xdt file in it
Non of them is does not work - nuget doesn't run install.ps1, nuget doesn't transform App.config.
There is a code from csproj:
<ItemGroup>
<Content Include="Content\app.config.install.xdt">
<PackagePath>content</PackagePath>
</Content>
</ItemGroup>
Nuget package contains this file... So I have no idea why it doesn't work.
Is this problem related to .NetStandard? What I'm doing wrong?

Executing ps1 scripts, and XDT transforms are both features that only work with packages.config, but not PackageReference. .NET Core (and I think .NET Standard) projects only work with SDK-style projects, and SDK style projects only support PackageReference. Packages.config only works with "old-style" projects, which may also PackageReference.
The way that Microsoft's ASP.NET Core libraries deal with this difference is that they no longer read settings directly from web.config. Instead the program has to register callback functions that will modify an existing in-memory options object. For example
services.AddMyService(options =>
{
options.setting = newValue;
});
This has some advantages to your users.
They are no longer limited to storing the configuration value in the location the library author demanded. They can choose to load configuration from a database, a configuration service, an xml file, a json file, or just hard-code it in the app. But it lets each developer choose what's best for their own system.
If the user overrides a setting that the package puts in the config file, and each update of the package overrides the user's preference, the user gets annoyed that the package doesn't respect their choice to change the default.
If the user doesn't want to override a setting that the package put in the config file, and the package author doesn't want to overwrite the config file each update, then it's very difficult for the package author to change a default value.
ASP.NET Core's new model is better for everyone because the package author creates the options object and pre-populates it with default values and then call the user's delegate method allowing them to change the settings they care about. If the package author wants to change a default value, they do so in their own code, publish a new package, and users that don't change the value get the new default, and users who explicitly set the value in their code keep using the value they want to, from whatever configuration store they want.
So, the TL:DR answer is that you can't do what you asked for with PackageReference projects, but I hope my longer answer has given you ideas how you can redesign your library which gives better both the package author and package user a better experience.

Related

How to override the "unsafeFlags" behavior of Swift Package Manager?

Swift Pacakage Manager allows a package manifest (Package.swift) file to specify build settings for targets.
As a security measure, some build settings can only be specified using "unsafeFlags" parameter. For example, specifying a framework search path outside the current directory using the -F build flag is considered "unsafe" because it could lead to code execution outside the package's own directory.
For packages downloaded from the internet, this could be considered an undesirable behavior. However, for locally-declared packages, this could be what we want to do.
However the design of SPM is such that any package that uses "unsafeFlags" cannot be depended on by another package.
Is there any override for this, for example, if we want to use unsafeFlags somewhere in a dependency structure of various locally-declared Swift packages?
Like, is there a setting we can supply for a package, framework, or app, so that it's allowed to depend on packages that use "unsafeFlags"?
Swift Package Manager allows unsafeOptions for dependencies specified by a commit hash. They're not allowed for versioned dependencies.
Example here.

Upload a NuGet package that is not mine

I have found a dll that is provided via Google Code and I couldn't find it in NuGet. I want this package to be available via a NuGet install, because I want to reuse it in several packages and NuGet seems like the perfect way to do this.
https://code.google.com/p/protobuf-remote/downloads/list
Is it possible for me to generate a nupkg out of these dll's and publish it to NuGet.org? What are the legal limitations to this action?
There are a number of other users that have run into this issue. It seems like the common solution is to create an "Unofficial" package and reference that for the time being (until Google publishes their library as a NuGet). Just make sure to very clearly label the package as unofficial. See these examples.
As for the legal ramifications...
Please look through protobuf-remote license and review the distribution and derived works details. Currently the license is GNU Lesser GPL. Sorry, but you'll have to make your own call on if publishing the NuGet package would be permitted under this license. ;)
I would recommend you instead create a local NuGet package source by pointing to a file share. This can be local on your computer or on a network file share.
Also, if you don't want to update every workstation, you can update the NuGet.config file in your project to point to this source and commit that config file in your source control repository for all users to get automatically. Just note that any change to a NuGet.config file requires you to restart Visual Studio.
And FYI, take a look at how you can chain multiple NuGet.config files.

Keeping SSIS packages under the source control

I store all SSIS packages in Subversion repository, their configuration files as well. Configuration file almost always stored in the same folder where package is.
Problem is - SSIS seems to always store path to configuration file (the one saved in the package itself) as an absolute path.
When someone else checks out folder with the package in the location different from where I had on my development PC the configuration file is not detected (because my absolute path is stored and it doesn't exist on the other developer PC). So another developer has to remove this configuration and add it again from where it is now on his local hard drive. Then changed package is saved which will cause new version to be committed. When I get that version from SVN it will no longer match local path on my PC.
On a related note: another developer may want to change values in configuration file as well. If I later get the latest version of everything from SVN package will no longer work on my PC.
How do you work around these inconveniences?
Another solution is to save your configuration in a database with an environment variable as the first configuration to tell it what database to look in, that's what we do. We have scripts to populate ssisconfig for each server in our source control, but the package uses the actual table data for the database in the environment variable we are using.
Anyone who has heard my SQL Saturday presentations knows I don't much care for XML and this is one of the reasons. A trick to using XML configuration with varying locations is to use an environment variable (indirect configuration) to direct SSIS where it can look for that resource. The big, big downside to this approach is you'd generally need to create an environment variable for each set of configuration files or have a massive, honking .dtsconfig file which becomes painful for versioning.
The option I prefer if XML configuration is a must is that the "variableness" is removed. Developers and admins get together and everyone agrees "there will be a folder everywhere SSIS is done to hold configuration files and that location is X" and then it's just a matter of solving for X. At a previous job, we used D:\ssisdata\configs
#HLGEM's approach of a table for configurations is hands down my favorite approach to SSIS configuration (until you get to 2012 and their project deployment model where configuration is an entirely different animal)
I add a folder called "config" under my projects folder, add it to source control and mantain the config file in this folder. You can also add it to the SSIS project if you like.
I think its a good solution because everybody can have this folder and dowload the config file.
When the package is deployed it will read the config file from where you inform in the deployment manifest so this solution wont impact your development

How to create a Nuget Package by hand (without Nuget.exe or Nuget Explorer)?

I've looked for descriptions of the files that go into a Nuget Package (.nupkg), but I have yet to find a definitive guide, most everything assumes you have to use Nuget Explorer, or the Nuget.exe -- but well, let's just say I'm obstinate.
Using the Nuget Explorer to create a package produces a directory with files that I'd like to create using a script or some other tool (besides Nuget.exe). So, given this simple directory layout generated by Nuget Explorer, I'm looking for definition of the .psmdcp file, the .rels file, the [Content_Types.xml] file, and of course the ProjectX.nuspec file.
I can find some details, or deduce them, for [Content_Typex.xml] and the .nuspec file. I tried making a package with just the lib/ dir, it's content, and a nuspec file, but apparently that isn't enough, and I get Package does not contain a manifest -- which I suspect means that the .nuspec alone isn't the full manifest.
lib/
ProjectX.dll
ProjectX.pdb
package/
package/services/metadata/core-properties/____hash____.psmdcp
_rel/
.rels
[Content_Types.xml]
ProjectX.nuspec
Is there no guide for making a .nupkg by hand? Is it really that complicated a process?
.nuspec defines properties about your package (the metadata) as well as a list of files to include in the package. There are plenty of descriptions of this around, so the bits that needs to be addressed are the files that are added by the tools:
.nupkg files follow the Open Packaging Convention. As you have figured out, it is really a .zip file with some predefined files. The _rels directory contain relationships between "parts". Think of a Word document containing images and Excel spreadsheet tables to get an intuition of "parts".
Packages mostly contain only one part; the package itself (but can probably contain sub-packages for modules). The _rels/.rels file defines the relationship for the main, top-level package. A relationship has an ID, a url that describes the kind of relationship and a target, which is the file which has this relationship to the package. Most packages has a relationship to the .nuspec file, which is of kind "manifest", and to the .psmdcp file, which is of kind "core-properties". The IDs of these relationships only need to be unique within the package, so they could be simply strings such as "R1", "R2", but for some reason they are "R" + 16 first bytes of GUID, in choco.
The core-properties seems to be mostly a rehash of the manifest file, dressed in Dublin Core tags instead of the nuspec; I guess in theory other programs could present the package based on these (if you embed it in a Word-document!). Probably psmdcp is an abbreviation of "Package Services Metadata Dublin Core Properties". Checking NuGet.Core/NuGet.Packaging/PackageCreation/Authoring/PackageBuilder.cs we see that the name of the file is a simply a GUID with "N" format (just digits). The lastModifiedBy property is the version information of the "choco" assembly itself; I guess you can really put anything there if you create the files yourself.
[Content Types.xml] defines the file format of extensions, in the form of MIME types. This is mostly boiler-plate.
So, in conclusion: Based on the .nuspec you can generate all the other missing files and put together the .nupkg yourself, even in a Powershell script.
I've written a blog post about how you could use the NuGet XSD:
http://www.xavierdecoster.com/post/2012/03/08/Hidden-gem-the-NuGet-package-manifest-XSD.aspx
Also, take a look at the NuGet package conventions in the docs:
http://docs.nuget.org/docs/creating-packages/creating-and-publishing-a-package#Package_Conventions
If you need more detailed hands-on, there's also a Pro NuGet book that goes in-depth into various scenarios:
http://www.amazon.com/NuGet-Professional-Apress-Maarten-Balliauw/dp/1430241918

How to read\write settings from a Visual Studio Project file using NuGet?

I'm interested in creating a NuGet package for a documentation tool I'm writing. Ideally, I'd like the user to not have to configure my tool in anyway. In order to do this, I need to be able to read some settings from the Project's .csproj or .vbproj file to get the path of the Xml documentation file generated by the compiler. I also need to add a post-build step to the project.
I've looked through their documentation but I haven't seen any mention of being able to do this. Is this possible? If so, is there any documentation or examples of this available?
Using PowerShell script, you can access the rich VS DTE object model. This allows your package to do all kind of things that NuGet doesn't have specific features for. Look at this help topic for some info on using init.ps1 or install.ps1.