Can Laminas Dependency Plugin be removed after the migration from ZF3 to Laminas? - zend-framework

I migrated an application from Zend Framework 3 to Laminas. During the migration, the migration script added the laminas/laminas-dependency-plugin dependency to the composer.json file. After that, I removed this (by running composer remove laminas/laminas-dependency-plugin). For now there are no errors and all the tests are "green", but nevertheless I would like to be sure that the package was really only needed for the migration and I don't have to expect any trouble caused by this missing package.
Is the laminas/laminas-dependency-plugin package needed after a successful completion of the migration from Zend Framework 3 to Laminas?

laminas/laminas-dependency-plugin is needed for the case where some of your dependencies want Zend Framework packages. It hooks into composer resolution to rewrite ZF package to its Laminas counterpart.
Each migrated Laminas package provides same versions that were originally released in Zend Framework, and provides composer replace for exact same version of ZF package.
For example, when some of your dependencies want laminas/laminas-stratigility and some other wants zendframework/zend-stratigility then composer will install laminas/laminas-stratigility to satisfy both dependencies. Dependency plugin will have no effect.
However, when some dependency wants zendframework/zend-inputfilter and nothing wants its Laminas counterpart then composer will install zendframework/zend-inputfilter. This is where dependency plugin comes into play and rewrites it to laminas/laminas-inputfilter
If nothing is installing zendframework/* packages, you are fine. laminas/laminas-dependency-plugin is not a hard dependency and you can remove it.
Another compatibility package laminas/laminas-zendframework-bridge is responsible for dynamically aliasing Zend namespace to Laminas when Zend Framework class autoloading is triggered.
If you are sure nothing in your dependency tree uses Zend Framework packages, you can also remove the bridge package by utilizing replace in the root composer.json like this:
"replace": {
"laminas/laminas-zendframework-bridge": "*"
},
Note that this approach is a hack and can potentially break some code unless you tightly control your dependencies. Generally it have negligible impact and removing it won't provide a noticeable benefit.

Related

Reducing dependencies for a .NET Standard class library?

I have converted some of my class libraries to .NET Standard with Visual Studio 2017.
This was easy, add a .NET Standard class library project in place of the original project and add all the files in there. The .csproj file even looks like a nuspec file now with package information and such. Inside the project options there was a checkbox for "Generate NuGet package on build", which I checked. Easy peasy.
However, .NET Framework consumers of my class library now gets a ton of dependencies, I counted at least 20 other nuget packages that were added, most of which was completely unecessary for my library. In other words, was "easy peasy too easy?"
Is this just a byproduct of me using .NET Standard as the only build output and I should add back a .NET Framework library as well?
Packages such as the following will be added to a project that consumes my library, even though they are completely unnecessary:
System.Security.Cryptography.*
System.Xml.*
System.IO.*
etc. there's plenty of packages being added. My library does "glorified" array analysis and doesn't require much at all.
The Visual Studio project is configured to target .NET Standard 1.0 and the only reference visible is the "NETStandardLibrary" so it's not like I added all of those myself.
I've inspected the package and it doesn't seem to list all of those either.
Can I add only the packages I need and still target .NET Standard 1.0?
My class library is open source here: https://github.com/lassevk/DiffLib
The nuget package is here: http://www.nuget.org/packages/difflib/2017.4.24.2347
This is quite a complex situation at the moment:
Can I add only the packages I need and still target .NET Standard 1.0?
Yes you can do it, but this is no longer recommended. In essence, .NET Standard is a specification that is made up of the packages referencing it. The supported way is to reference NETStandard.Library since it guarantees to bring you all needed compilation references and logic that you need in order to build correctly.
Beginning with the upcoming netstandard2.0, NETStandard.Library will be a flat package without dependencies and the individual packages will be removed from the dependency tree if your project or any other project references them. Also, NETStandard.Library will not be published as a dependency - so if you build a netstandard2.0 library, the resulting NuGet package will have no dependencies. (NETStandard.Library.NETFramework is required to be installed when using it in .net framework projects - NuGet is supposed to do this automatically).
That being said, if you really want to do it, you can set
<DisableImplicitFrameworkReferences>true</DisableImplicitFrameworkReferences>
in the csproj file and then add items like <PackageReference Include="System.[Something]" Version="4.3.0" /> for everything you need.

How to know will nuget package work on .NET Core?

I would expect some kind of filter to exists on website or in console.
This isn't easy right now, unfortunately. There's an issue open on the NuGet Github about adding a filter to the website.
Right now, the best way to tell if a package will work with .NET Core is by examining the frameworks it supports in the Dependencies section.
If .NETStandard is listed, the package supports .NET Core via the .NET Platform Standard:
If a package's Dependencies section doesn't mention .NETStandard, or the Dependencies section is completely empty, it does not support .NET Core:
Setup a .NET Core project in the version you want. I keep 1.1 and 2.0 projects around for futzing with this. Then try and add the nuget to the project.
For instance, ASPOSE will NOT add to a 1.1 project, but will add to a 2.0 project.
Easiest route in the short term until they fix this somehow.
Obviously this is no guarantee it still works but gives you a good idea if its api compat.

Convincing Nuget that I've met a dependency from another package

I have a project where I'd like to use https://www.nuget.org/packages/Bootstrap.Datepicker/, so being a good modern developer I tell VS to add that nuget package. Which is cool. But along with it comes Bootstrap 2.3.1, which I know is a dependency of that package. But my project already has the Bootstrap Less Source (3.2.0.1) package installed, and I'm concerned about having two different "instances" of the "same" package in my project. Another developer on my team has pointed out that any and all Nuget packages that are based on bootstrap probably will require the default one, not the less source package we're using, even though that works best for us.
Is there some way in nuget to tell it to ignore dependencies, or convince it that instead of the dependency it's expecting, it's been met in another way?

Installing multiple packages with composer?

I am trying to install the latest version of Zend Framework 2 with composer and also install at least one other package at the same time. The other package is another Zend Framework package. The two packages are:
zendframework/zendframework
zendframework/zendservice-twitter
I added zendframework/zendservice-twitter to the require section of that file. It doesn't look like there is any other section to use to install multiple packages in the same directory tree. But when I try to add zendframework/zendservice-twitter to the require section of the composer.json file, it tells me that zendframework/zend-uri is required. But zendframework/zend-uri is installed by the zendframework/zendframework package. It is listed in the replace section of that composer.json file. So apparently the replace section is not the place to add other packages that need to be installed. But you can't have multiple composer.json files in the same directory either, so is it even possible to install Zend Framework 2 and ZendServiceTwitter in the same installation with composer?
When I download a package as a zip file from https://packages.zendframework.com/#composer, I get a composer.json file in the zip file, but it does not have the same repository setting that it says to use at https://packages.zendframework.com. So I am not sure if that composer.json file is intended to be edited in order to upgrade or reinstall.
Isn't there some way to tell composer that this is a circular dependency?
I don't see the circular dependency. The twitter package requires zend-uri, and zend-uri is provided by the main Zend Framework package that you've already installed.
I just tried this out on a fresh checkout of the skeleton app and it worked fine. All I did was add the twitter package to the require section of my composer.json:
"require": {
"php": ">=5.3.3",
"zendframework/zendframework": "2.3.*",
"zendframework/zendservice-twitter": "~2.1.0"
}
(2.1.0 is the latest version of it at the moment.) You don't need to touch the replace section.

Varying dependencies depending on target project type

I have a package Ninject.Extensisons.Wcf which shall be installed differently depending on the type of the project to which it is installed. In the case where WCF is hosted in IIS (any project containing global.asax) a second package Ninject.Web.Common needs to be installed together with the package. For all other project types such as libraries, Console, WinForms, WPF applications this package should not be installed.
Is it somehow possible to achieve this e.g., using a powershell script? Or do I have to deploy two different packages in this case?
Unfortunately the current nuspec file does not provide for managing dependencies based on project type. We currently support targeting different framework versions, but that doesn't apply in your situation.
It is recommended that all dependencies are handled using package references. Although it would be technically possible to download and install a package using a PowerShell script, this is not supported and will most likely break in future versions.
First determine if it would actually be a problem to reference a web package in a non-web project. Just because assemblies are referenced, if they are not used, it should not have an impact.
If it turns out that having the web dependency causes undesirable side-effects, then you'll need to create separate packages.
I would split up your package into logical pieces. As you state, you have a package that is used by non-web projects. Web projects require a dependency on a different package.
So now you have 2 logical packages:
MyProject
MyProject.Web
MyProject (dependencies)
SomeOtherPackage
So a user would Install-Package MyProject for non-web projects, and Install-Package MyProject.Web for web projects.
At this point you would be done and everything would be fine. But I think you should consider another step. One of the issues I see with these split packages is that I have to figure out which particular package I need to install. I have to know that I need the "Web" version.
At this point, determine the typical use case for your package. If 90% of your users will be installing the Web version, then I would make a "meta" package that simply has dependencies for your common packages.
In your case I would make 3 packages:
MyProject (meta package)
MyProject.Web
MyProject.Web
MyProject.Core
SomeOtherPackage
MyProject.Core (common non-web package)
By creating the "meta" package, you can reserve the "short" package name for the most common case. This meta package only has dependencies to other packages.
A good example of this is the SignalR package.
Hope this was helpful.