我有一个.NET核心解决方案,由三部分组成:
ASP.NET核心网站
业务逻辑.NET核心DLL
数据访问.NET核心DLL
我现在需要从我的业务逻辑DLL中使用.NET框架nuget包(它不在我的控制范围内)。
根据这个答案中的建议,我将我的业务逻辑项目更改为target.net 4.6.1(net461)。
然而,这迫使我为数据访问项目(从业务逻辑项目中引用)做同样的事情,并且(尽管我还没有到那里)我想我也必须为网站项目做同样的事情。
我认为.NET核心在很大程度上是.NET框架的一个子集,除了只需要"更大"的框架之外,不会有任何功能上的改变,那就好了。但是,重新确定了我的数据访问项目的目标之后,我发现有一些东西丢失了。例如,它现在使用C_7值元组来反对我。
虽然我可以通过nuget包添加回值元组,但我还需要进行其他更改(dataAnnotations似乎已消失/移动),而且我似乎正在以.NET框架的方式进行所有操作。
有办法解决这个问题吗?我觉得我在拉一根绳子,最终我会回到ASP.NET MVC…
- 最近我也遇到过类似的问题…我建议通过努力重新组织您的项目,使一个项目成为您的"框架桥接"(即.NET 4.6),另一个项目是.NET核心项目。最终您将得到两个应用程序(一个.NET 4.6,另一个.NET标准)
- @斯韦克:我不介意花时间去做正确的事情,但我真的不知道怎么做。如果我让我的业务逻辑项目.NET 4.6,那么它就不会让数据访问项目保持为.NET核心。所以只要我在.NET 4.6上有一个项目,整棵树就好像被"污染"了。
- 这里有一个小的概念,我的意思是你现在可以扩大和成长(我会写一个答案,当我有时间)。使用.NET标准创建一个项目(仔细阅读),然后在项目中创建一个名为foo的对象,并给出几个基本属性。此项目必须与提取任何非网络标准的依赖项保持隔离。您可以在.NET核心和.NET框架中引用此对象…让我们使用一个API(如Web API)并在两个应用程序之间传递这个对象(foo)。所以我们有2个应用程序+1个共享类库将它们连接在一起…
- 一行回答:.NET标准是两者之间的最低共同点,因此创建一个独立的.NET标准类库,并使用它来桥接两个不兼容的应用程序。
- @SVEK:你是说两个独立的应用程序作为独立的进程运行,通过HTTP进行通信吗?在我描述的三层(web/logic/data)架构的上下文中,这几乎就像递归!:-)逻辑层需要扩展以拥有自己的Web API????我很困惑。我真希望我没有开始沿着这条路走。
- 您可以选择您最喜欢的API品牌,甚至命名管道也可以工作。主要的一点是这两个项目是不兼容的,除非您可以使依赖项.NET标准化。
- 要证明这一努力的合理性,请将其视为将您的体系结构转换为微服务模式。这种分离将允许业务层建立在生锈的古老代码之上,而您的前端将得到一个改版。
- @Svek:问题是我需要使用的nuget包不是我的-我无法控制它,所以它将保持.NET 4。我最初的问题是"我的整个解决方案现在必须改变吗",我想你是说答案是"是的"。同一解决方案中的任何项目都必须更改。我可以有一个完全独立的解决方案来隔离"旧"东西,然后"通过电话"与它交谈,但我不能将它合并到我现有的解决方案中。这太惊人了——而且是毁灭性的。
- 我不可能仅仅为了支持这个单一的功能而构建一个全新的应用程序(和跨应用程序API)。即使只是为此设置部署机制,也需要大量的工作。所以看起来我需要放弃.NET核心。反过来,我想这意味着我需要放弃ASP.NET核心…在我的网络项目上花费了这么多周的努力:-(((
可以同时针对两个框架。我在一个项目中工作,我希望以.NET核心2.0为目标,但需要使用.NET框架包。
为此,请打开.csproj文件并用新的targetframeworks标记替换targetframework标记。
net461;netcoreapp2.0
不幸的是,在Visual Studio中不可能通过UI来实现这一点。进行此更改并重新加载Visual Studio后,目标框架将为空。
- 我很有希望,但这似乎无济于事。如果我让我的业务逻辑项目同时以核心和框架为目标,那么它会抱怨我的数据访问项目(以核心为目标)不兼容。如果我让数据访问项目同时面向核心和框架,那么它将不会编译,因为它没有valuetuple和dataannotations等——这是我以前的工作。我误解了吗?
- 我认为这个答案有点遗漏了这一点。我不想创建一个可以被两个不同的.NET版本使用的库。因为我的Web项目是一个ASP.NET核心Web应用程序,所以我的库需要由ASP.NET核心使用。因此,多目标业务逻辑DLL没有帮助,除非它与ASP.NET核心兼容,并且据我所知,如果它具有.NET框架依赖性,这是不可能的。(很明显我没办法了)。
另一个可能的解决方案(也许不是你想要的)是将你的项目分成更小的项目,然后业务和数据逻辑可以转换成服务(SOA-https://en.wikipedia.org/wiki/service-oriented_architecture)
这看起来似乎是"长途跋涉",但它的最终优势在于,分离的逻辑服务和主项目在技术和大多数其他需求方面相互独立。
再一次,我意识到这可能不是你想要的,但我觉得这是一个有效的选择,在这里分享可能很有用。
- 这就是@svek在评论中所说的。我明白了,但是考虑到所产生的好处,我认为这是非常昂贵的,特别是在公司环境中,所有这些新组件都需要发布/部署管道。相对于在.NET核心中开发(而不是在.NET框架中)的几乎零的好处而言,这是非常昂贵的。
- @我完全理解你的感受。不幸的是,与.NET框架相比,.NET核心仍然是相当新的,但是它一直在增长,.NET核心3.0的发布就在眼前,这给我们带来了许多新的东西。当然,这目前对您没有帮助,但也许其他人可以从您的问题和此处发布的答案和评论中获益。
在与@svek聊天时,我说服自己必须放弃整个Web项目,重新开始一个老式的ASP.NET MVC Web项目(或割断我的手腕),现在我发现情况并非如此。
以下是我认为的要点:
如果使用的nuget包使用的是.NET 4.6,则不能在以.NET核心为目标的dll中使用该包。
您可以(根据@matt h的答案)有一个以.NET核心和.NET 4.6为目标的dll,但这并没有真正的帮助,因为只创建了两个版本的dll,并且只有.NET 4.6版本可以使用nuget包。因此,您的DLL需要以.NET 4.6为目标。
通过扩展,解决方案中直接引用该dll的每个项目也需要以.NET 4.6为目标。所以,是的,这种传染确实传播了。-(
在我的例子中,这意味着我的ASP.NET核心Web应用程序也需要以.NET 4.6为目标-我起初假设这意味着完全放弃ASP.NET核心,并放弃我在Web项目上所做的大量工作。但事实并非如此。
在.NET 4.6上运行ASP.NET核心Web应用程序是可能的(尽管这看起来有点不合逻辑)。事实上,在Visual Studio中创建新的ASP.NET核心Web应用程序时,您可以选择在此时将.NET 4.6作为目标。这将生成一个不同的项目文件,具有额外的nuget依赖项等。请参阅此问题。
所以,我最终的解决办法是:
已将所有DLL更改为目标"net461"(通过编辑项目文件)。
"polyfilled"一些结果丢失的内容(例如,通过添加nuget包来获得valuetuple支持,以及通过添加显式包引用来获取system.component.dataAnnotations)。
围绕ASP.NET核心Web项目进行黑客攻击,以"net461"为目标,这意味着更新各种引用并添加更多nuget包,以使ASP.NET核心组件正常工作。(我创建了一个新的Web项目的两个版本——一个针对.NET核心,另一个针对.NET 4.6——以了解区别是什么,以及我必须做什么更改)。
完成所有这些之后,我的项目将正确编译和运行。这是一种巨大的解脱。
- 我很高兴你能解决这个问题。由于ASP.NET核心使用.NET标准,因此您可以始终以NET4.6为目标,因为它是兼容的。请注意,ASP.NET核心与.NET核心不同,以供将来参考!:)不管怎样,您唯一失去的是为跨平台编译应用程序的能力。
- 我最初的理解是,因为你的问题是,目标是让代码保持.NET核心(即跨平台&;.NET标准)--然而,似乎我们有一些误解,你并不介意针对NET46毕竟。这就是很多困惑的所在。
- @斯韦克:对不起,我同意我的问题——以及随后的问题——一直很模糊。这是因为这对我来说都是新的,所以我真的不知道该如何界定这个问题。正如您所猜测的,我还对ASP.NET核心和.NET核心之间的关系感到困惑。谢谢你的帮助。
- 我很高兴你能把它整理好。这才是最重要的!