Does my whole solution have to be .NET Framework r

2019-08-04 05:26发布

问题:

I have a .NET Core solution comprising 3 parts:

  1. ASP.NET Core website
  2. Business Logic .NET Core DLL
  3. Data-access .NET Core DLL

I now have a need to use a .NET Framework NuGet package (which is not within my control) from my business-logic DLL.

Following the advice in this answer, I changed my business-logic project to target .NET 4.6.1 (net461).

However, this then forced me to do the same for the Data-access project (which is referenced from the Business-logic project), and (though I haven't got there yet) I presume I'll also have to do that for the website project.

I thought that .NET Core is largely a subset of .NET Framework, and that there would be no functional change beyond merely requiring the "bigger" framework, which would be OK. However, having re-targeted my data-access project, I now find that there's some stuff missing. For example, it now objects to me using C#7 value tuples.

Although I can add back the value tuples via a NuGet package, there are other changes I need to make (DataAnnotations seems to have gone/moved), and it rather seems like I'm drifting back towards everything being done the .NET Framework way.

Is there any way around this? I feel like I'm pulling on a piece of string that will end up with me going all the way back to ASP.NET MVC...

回答1:

It is possible to target both frameworks at the same time. I worked on a project where I wanted to target .Net core 2.0 but needed to use a .NET Framework package.

To do this, open up your .csproj file and replace the TargetFramework tag with a new TargetFrameworks tag

<TargetFrameworks>net461;netcoreapp2.0</TargetFrameworks>

Unfortunately, it isn't possible to do this through the UI in visual studio. After you make this change and reload Visual Studio, your target framework will just be blank.



回答2:

Having convinced myself during my chat with @Svek that I'd have to abandon my whole web project and start again with an old-style ASP.NET MVC web project (or slit my wrists), I've now discovered that this is not the case.

Here's what I think are the salient points:

  1. If you're using a NuGet package that uses .NET 4.6 then you cannot use that in a DLL that targets .NET Core.

  2. You can (per @Matt H's answer) have a DLL that targets both .NET Core and .NET 4.6 - but that doesn't really help, since all that does is create two versions of the DLL, and only the .NET 4.6 version can use the NuGet package. So, your DLL needs to target .NET 4.6.

  3. By extension every project in your solution that directly references that DLL also needs to target .NET 4.6. So yes, the contagion does spread. :-(

  4. In my case, that meant that my ASP.NET Core web app also needed to target .NET 4.6 - and I assumed at first that this meant abandoning ASP.NET Core altogether, and throwing away a considerable amount of work I'd done on my web project. However this is not the case.

  5. It is possible to have an ASP.NET Core web app run on .NET 4.6 (even though that seems somehow illogical). In fact, when creating a new ASP.NET Core web application in Visual Studio, you can choose to target .NET 4.6 at that point. This produces a different project file, with extra NuGet dependencies etc. See this question.

So, my eventual solution was:

  1. Changed all my DLLs to target "net461" (by editing the project file).

  2. "Polyfilled" some of the stuff that was missing as a result (e.g. by adding a NuGet package to get ValueTuple support, and by adding an explicit package reference to get System.Component.DataAnnotations).

  3. Hacked around the ASP.NET Core web project to also target "net461" which then meant updating various references and adding more NuGet packages to get the ASP.NET Core components working. (I created two versions of a new web project - one targeting .NET Core and one targeting .NET 4.6 - in order to see what the difference was, and thus what changes I had to make).

Having done all this, my project compiles and runs correctly. Which is a huge relief.



回答3:

Another possible solution (albeit perhaps not what you want) is to separate your project into smaller projects, where the business and data logic can then be converted to services (SOA - https://en.wikipedia.org/wiki/Service-oriented_architecture)

This might seem to be "the long way round", but it does have it's eventual advantages in that the separated logic services and the main project are independent of each other in terms of technology and most other requirements.

Again, I realize this might not be what you're after, but I felt it's a valid option, and possibly useful to share here.