I am having trouble wrapping my head around framework dependencies of ASP.NET Core Web API and .NET Standard PCLs.
I am creating a new web API (microservice) that will be used as an API gateway, I created a new project in VS2015 (update 3, latest .net core tools) and it compiles and runs fine.
I then added some .NET Standard PCL projects to use to separate out POCOs, Repository layers etc. These all reference each other fine, however when I try to add a reference from my ASP.NET Core Web API I cannot use any of the classes defined in my PCLs.
After some research is seems to be down to the fact that I am targeting different frameworks in the projects, the frameworks section of project.json for the Web API reads:
"frameworks": {
"netcoreapp1.0": {
"imports": [
"dotnet5.6",
"portable-net45+win8"
]
}
},
And for the PCLs it initially read:
frameworks": {
"netstandard1.6": {
"imports": "dnxcore50"
}
}
It seems clear this is where the incompatibility arises.
To rectify this I attempted to make the .Net core project reference the .Net Standard framework such that it could use the PCLs, however everything I tried failed to allow me to reference the projects.
The only way I have gotten this to work is to do the inverse and make the PCL libraries reference netcoreapp1.0, which feels very wrong.
My full .Net standard project.json now reads:
{
"version": "1.0.0",
"dependencies": {
"NETStandard.Library": "1.6.0"
},
"frameworks": {
"netstandard1.6": {
"imports": "dnxcore50"
},
"netcoreapp1.0": {
"imports": [
"dotnet5.6",
"portable-net45+win8"
]
}
}
}
And my full .Net Core Web Api Project reads
{
"dependencies": {
"Microsoft.NETCore.App": {
"version": "1.0.1",
"type": "platform"
},
"Microsoft.AspNetCore.Mvc": "1.0.1",
"Microsoft.AspNetCore.Routing": "1.0.1",
"Microsoft.AspNetCore.Server.IISIntegration": "1.0.0",
"Microsoft.AspNetCore.Server.Kestrel": "1.0.1",
"Microsoft.Extensions.Configuration.EnvironmentVariables": "1.0.0",
"Microsoft.Extensions.Configuration.FileExtensions": "1.0.0",
"Microsoft.Extensions.Configuration.Json": "1.0.0",
"Microsoft.Extensions.Logging": "1.0.0",
"Microsoft.Extensions.Logging.Console": "1.0.0",
"Microsoft.Extensions.Logging.Debug": "1.0.0",
"Microsoft.Extensions.Options.ConfigurationExtensions": "1.0.0",
"Company.Product.Microservices.Gateway.Business": "1.0.0",
"Company.Product.Microservices.Gateway.DomainObjects": "1.0.0"
},
"tools": {
"Microsoft.AspNetCore.Server.IISIntegration.Tools": "1.0.0-preview2-final"
},
"frameworks": {
"netcoreapp1.0": {
"imports": [
"dotnet5.6",
"portable-net45+win8"
]
}
},
"buildOptions": {
"emitEntryPoint": true,
"preserveCompilationContext": true
},
"runtimeOptions": {
"configProperties": {
"System.GC.Server": true
}
},
"publishOptions": {
"include": [
"wwwroot",
"**/*.cshtml",
"appsettings.json",
"web.config"
]
},
"scripts": {
"postpublish": [ "dotnet publish-iis --publish-folder %publish:OutputPath% --framework %publish:FullTargetFramework%" ]
}
}
As I said earlier, the framework references here seem incorrect. I would assume that a netcoreapp framework based project could reference a .NET Standard project compiled project directly, without the PCL itself having to know anything about netcoreapp, it is a PCL after all.
What is the correct what to structure a project like this, it feels this should be the "default" setup of any ASP.NET Core project however so far it has not been simple to set up and I cannot find any documentation that relates to this surely common scenario. Perhaps that is because my understanding of Core and Standard is incorrect and I'm not doing it right, or perhaps my config is just wrong. Please let me know either way how I should achieve a structure like this correctly.
netcoreapp1.xis only here for applications, not for class libraries. Applications are in general assemblies (dll or exe) with an entry point (static Main method, like console, asp.net core web applications or unit test projects). That being said, your class libraries shouldn't havenetcoreapp1.xat all, only your application.netcoreapp1.0project can referencenetstandard1.xnetcoreapi1.xin the PCLs, however I get no intellisense and Visual Studio cannot see the references to my PCLs, despite it compiling (from VS). So while that works it is not an acceptable solution.