Nuget package the depends on 1 of N Nuget packages? - asp.net-mvc

I am working on an open source project MvcSiteMapProvider getting it ready for deployment. It is a library package that supports MVC2, MVC3, and MVC4 as well as .NET 3.5, .NET 4.0, and .NET 4.5.
Based on Nuget Package: Use Different MVC Version When Available, I have come to the conclusion that I need to make a Nuget package for each version of MVC and let Nuget's internal version detection take care of the different .NET versions, like this:
MvcSiteMapProvider.MVC2
MvcSiteMapProvider.MVC3
MvcSiteMapProvider.MVC4
However, in addition to a library DLL, I have different files (Dependency Injection configuation, MVC DisplayTemplates, etc.) that need to be deployed to the target project. These files MUST NOT be updated when the new version of the main project is updated because they will likely contain end-developer edits that I don't want to overwrite.
So, it is clear that these need to be in their own Nuget packages for this and other reasons. However, these other packages need to depend on the main MvcSiteMapProvider.MVCx projects, just to ensure one of them has been installed.
It doesn't make sense to make a separate Nuget package for each version of MVC for each of these other packages - they are all exactly the same except for this one dependency. Ideally what I would like to do is make a single Nuget package that depends on either MvcSiteMapProvider.MVC2, MvcSiteMapProvider.MVC3, or MvcSiteMapProvider.MVC4 and if none of them are available, install the one that matches the MVC version of the target project, but how would I accomplish this? If that is not possible, what other options do I have than creating large number of Nuget packages (one for each MVC version dependency) that grows exponentially with each new MVC release?
To clarify, I have other Nuget packages like this:
MvcSiteMapProvider.Web
MvcSiteMapProvider.Configuration.Autofac
MvcSiteMapProvider.Configuration.Ninject
MvcSiteMapProvider.Configuration.StructureMap
MvcSiteMapProvider.Configuration.Unity
MvcSiteMapProvider.Configuration.Windsor
I am trying to avoid having to change that to:
MvcSiteMapProvider.MVC2.Web
MvcSiteMapProvider.MVC2.Configuration.Autofac
MvcSiteMapProvider.MVC2.Configuration.Ninject
MvcSiteMapProvider.MVC2.Configuration.StructureMap
MvcSiteMapProvider.MVC2.Configuration.Unity
MvcSiteMapProvider.MVC2.Configuration.Windsor
MvcSiteMapProvider.MVC3.Web
MvcSiteMapProvider.MVC3.Configuration.Autofac
MvcSiteMapProvider.MVC3.Configuration.Ninject
MvcSiteMapProvider.MVC3.Configuration.StructureMap
MvcSiteMapProvider.MVC3.Configuration.Unity
MvcSiteMapProvider.MVC3.Configuration.Windsor
MvcSiteMapProvider.MVC4.Web
MvcSiteMapProvider.MVC4.Configuration.Autofac
MvcSiteMapProvider.MVC4.Configuration.Ninject
MvcSiteMapProvider.MVC4.Configuration.StructureMap
MvcSiteMapProvider.MVC4.Configuration.Unity
MvcSiteMapProvider.MVC4.Configuration.Windsor

Looking at your source code, it seems like you are referencing multiple versions of the Microsoft.AspNet.Mvc package in MvcSiteMapProvider project. I am not sure this is working as you expect it to since there can be only one version of System.Web.Mvc that can be put in the bin folder during the compilation process (the latest version 5.0.0 will be used).
So any code in your package that depends on Mvc V3 or V4 is not really getting the dll it expects.
Since most of the packages you referenced above like Autofac also have integration package that target specific MVC versions,you may not have an option but to split your package into smaller packages like you mentioned in your post.
A better approach to this problem would be to separate the Core functionality provided by your package which does not have dependency on any version of MVC. You can then create different wrapper packages that depend on your core package and also on a specific version of Microsoft.AspNet.Mvc. And create similar packages for each different Configuration has a nuget dependency on third party packages like Autofac (eg Autofac.Mvc5) and its corresponding version of your MvcSiteMapProvider.MvcX package

Related

Is it safe to exclude Scaffolding packages from publish version?

I have Microsoft.VisualStudio.Web.CodeGeneration.Design nuget in a project.
Can it be safely excluded from publishing (<ExcludeAssets>runtime</ExcludeAssets>)?
Is there scenario, when during runtime, code has dependency on this package?
As I understand this package is used only for generating the code during development.
I don't see any reason to add its dll in published code.
Is it safe to exclude Scaffolding packages from publish version?
As the package describes,
Code Generation tool for ASP.NET Core. Contains the
dotnet-aspnet-codegenerator command used for generating controllers
and views.
It only works for generating code for views or controllers during developing and the project itself does not depend on the package at runtime.
So it is safe to exclude that nuget package from publishing using your method. And you do not have to worry too much about it.

Adding .net 4.5 reference to Asp.net vNext project

I'm trying to add .net 45 reference to a asp.net 5 starter web project..and i'm getting this errors.
While it is true that you can target multiple frameworks in a way similar to how you've done in your example, I think you will probably not be able to get the StarterWeb project to run under .NET 4.5 without some significant changes.
When dealing with multiple frameworks, Visual Studio 2015 will actually provide a lot of help if you hover the mouse over the code with errors:
One obvious difficulty in getting the StarterWeb project working is that between MVC 5 and 6, a number of pieces have been moved into new namespaces and broken up into different assemblies. Most notably, the MVC 5 package depends on System.Web, whereas the 6.0 beta that is used by the StarterWeb project does not. With the MVC libraries moved, the Authorize attribute is now in Microsoft.Aspnet.Mvc, whereas in earlier versions it belonged to System.Web.Mvc.
While in theory you could probably target different versions of MVC across the frameworks, in practice that would probably not be worth the trouble. Even if you find Authorize, there's no guarantee that it will be the "same" one, even if it compiles.
If that is a route you want to go (or just when targeting multiple frameworks in general), you have control over which packages are used by which framework in the project.json file.
If packages are compatible with all of the targeted frameworks, you can leave them in the parent dependencies area of the project.json file, but when they are specific to a given framework, you need to add a child dependencies section to that particular framework's configuration. In the case of .NET 4.5, you can also add familiar framework assemblies (as opposed to NuGet packages) by adding a frameworkAssemblies section.
You will end up with something like this:
"dependencies": {
"SomeCommonPackage":"1.0.0"
},
"frameworks": {
"aspnet50":{
"dependencies":{
"Aspnet50SpecificPackage":"1.0.0"
},
"net45":{
"dependencies":{
"NET45SpecificPackage":"1.0.0"
},
"frameworkAssemblies":{
"System.Web":"4.0.0.0"
}
When you target these different frameworks, you will often find that at least some code will have to framework-specific. To handle this, you can add compiler directives for the various using statements and the actual code that depends on packages only available in one framework or another.
For example, you may end up with areas that look something like this:
SomeType result;
#if ASPNET50
result = SomeMethodNotAvailableIn45( );
#endif
#if NET45
result = EquivalentMethodIn45( );
#endif
Obviously that is overly simplistic, but it gives you the basic formula:
Put shared dependencies in the root dependencies section
Put dependencies specific to a given framework in its own dependencies section
Use compiler directives for framework-specific code that can't be shared
I also would recommend you take a look at Rick Strahl's excellent blog post to see a great walk-through of targeting multiple frameworks with more detail and lots of screenshots. One nice feature of the new project system is that it can easily create a NuGet package for all of the frameworks you choose to target, and he goes into more detail about that as well.
Adding a .NET 4.5 project that is in the same solution as a reference to a vNext project still doesn't work in VS2015 RTM/ASP.NET Beta5. The project just can't seem to find the source/binary and tries looking in nuget for it. I followed the recommended steps with global.json, dnx451 dependencies.
My work around was to
Make the .NET 4.5 project pack a nuget package in post build step
Add a package source location to the local package file
This way I can speed up development cycle without requiring a nuget publish. One wrinkle is that relative package source paths using a $ are replaced with absolute paths.

NuGet in a project template

This question is about how to set up a project template to satisfy dependencies.
First, some context.
I have a MVC4/Durandal project that I'm trying to turn into a project template that distils all the goodness from a recent project, for re-use.
After creating a new project, adding all the non-standard good bits and shaking down the stub project so that it compiles and runs properly, I copied the project folder and plonked it on another computer with a freshly minted VS2013 installation, to see what broke.
The following were MIA:
Antlr.Runtime
System.Net.Http.Extensions
System.Net.Http.Primitives
System.Web.Optimization
WebActivator
WebGrease
There are a couple of issues making it less than obvious to me as to how I should proceed.
Installation of these things happened so long ago that I really couldn't say how they got onto my development workstation
In many cases package dependencies mean that installing one NuGET package will implicitly satisfy other dependencies
I don't know how set up a project template so that it causes NuGET package(s) to be installed
A bit of guidance would be appreciated, not to mention advice on best practice.
Update
It appears there is direct NuGet support for project templates, I'm still reading about it here and also here.
Since allowing NuGet to automatically resolve dependencies is a good way to ensure compatible versions are installed in the right order, the remaining question is looking at the missing assemblies, how can I determine the most dependent package(s)?
It seems that omitting the packages folder produces a slim template, and the projects produced therefrom install the missing files as soon as you start a build. That's good enough for me.
I would simply start with a blank ASP.NET 4.5 MVC project. The most basic dependencies should be satisfied then. NuGet has basic packages for Mvc and other packages you may need. NuGet packages are designed to self contain the missing assemblies they need. They'll get published in IIS when you deploy so you don't install anything on the server.

Missing reference to System.Web.Mvc in Asp.net Unit Test?

I recently made some unit tests for my Asp.NET MVC application, or I tried to, it keep telling me "The type 'System.Web.Mvc.Controller' is defined in an assembly that is not referenced. You must add a reference to assembly 'System.Web.Mvc, Version=5.1.0.0, Culture=neutral.' Then I tried to add a reference to the above mentioned, but was only able to choose version 4.0.0.0 and now it tells me that my project already uses version 5.1.0.0, which is a higher version. What to do?
Thanks a bunch!
MVC 5 comes in from a NuGet package. Just as it did with the main MVC web project in your solution. Install MVC via NuGet into your Test project, and you should be good to go.
An educated guess, but you might have obtained the newer version via a nuget package(some of the newer MVC project templates do this), and thus it is not installed in GAC. Use the nuget package manager for the MVC project to determine if this is the case, and if so then mystery solved.
In the test project you can add the same package, or use the addreference->Browse to browse into the nuget dependencies and poke around under the MVC project till you find the DLL(it will be in the file system somewhere under SolutionName/MvcProjectName/packages).

Are Umbraco and NuGet packages interchangeable?

I'm building websites in Umbraco and they all use similar components and base templates. The obvious best practice is to create packages that install these things ready. But I can't tell how to do things like add project references in Umbraco, and I can't tell how to create document types (a database object) in NuGet.
I've not been able to find a good comparison of abilities - what one package can do that the other can't - to be able to choose one or the other types of package. Or will I have to use both types of packages for different jobs (I don't want to go down this route if I can help it, since some features may require both packages).
EDIT for clarification, hopefully this will help. I'm trying to ask a blanket question to find out whether it is possible to use only one packaging system, rather than two. I want to avoid installing 2 different packages to get something to work properly.
Can a NuGet package trigger an automatic install of an Umbraco package?
Can a NuGet package create Umbraco objects, like document types, etc?
Can an Umbraco package add assembly references to a project?
I'm not sure where you're trying to use NuGet in Umbraco, the Umbraco packaging system isn't NuGet based, it's entirely different to NuGet (caveat - the next version of Umbraco will use NuGet for packaging).
The Umbraco package system, as currently defined, is capable of deploying any file into your target project be that CSS, JavaScript, Templates, Assemblies, User Controls, etc, as well as data into your database (Document Types, Content, etc).

Resources