我们有一个在ASP.NET 4中工作并使用HttpContext.Current
的库。我们知道我们can't use HttpContext.Current
in ASP.NET Core但应使用IHttpContextAccessor
。
我们如何更改此库,以便两者支持ASP.NET 4(使用HttpContext.Current
)和ASP.NET Core(IHttpContextAccessor
)并打包为一个 NuGet包?
答案 0 :(得分:1)
一种可能性:
创建三个库。
1和2具有相同的程序集名称,Factory仅引用两者中的任何一个。
此时,文件夹中只有两个程序集作为参考。工厂和参考中的其中两个。
使用所有三个程序集创建一个nuget包。 1和2进入单独的文件夹,我们称之为aspnet4和aspnet5。
包还包含aspnet项目使用的目标文件。目标文件根据aspnet项目中存在的属性将factory和其中一个库复制到references文件夹中。此属性可能类似于aspnet = aspnet5。
这可能是一件太大的事情,可能存在更简单的解决方案。我会想到一个更简单的解决方案。
//4. AspNetUsageBaseClass Assembly
namespace AspNetUsage
{
//rest of code
public abstract AspNetUsageBaseClass
{
//rest of code
public abstract void HttpContextIHttpContextAccessor();
}
}
//1. AspNetUsage Assembly, Reference AspNetUsageBaseClass Assembly
using AspNetUsage;
public class AspNetUsage:AspNetUsageBaseClass
{
public override void HttpContextIHttpContextAccessor()
{
//HttpContext based code
}
}
//2. AspNetUsage Assembly, Reference AspNetUsageBaseClass Assembly
using AspNetUsage;
public class AspNetUsage:AspNetUsageBaseClass
{
public override void HttpContextIHttpContextAccessor()
{
//IHttpContextAccessor based code
}
}
现在共有3个集会。一个基类组件。另外两个实现特定功能。 内部nuget包结构应该是:
AspNetUsageBaseClass.dll
- 基类汇编
AspNet4\AspNetUsage.dll
- HttpContext程序集
AspNet5OrCore\AspNetUsage.dll
- IHttpContextAccessor程序集
AspNet.target
- 这将在asp网络项目中导入,并根据属性的值提取两个dll中的一个。
在AspNet项目中你可以:
AspNetUsageBaseClass context = new AspNetUsage();
context.HttpContextIHttpContextAccessor();
这不是基于Factory
模式的,但可以基于某些修改将其扩展为Factory
模式。
由于我在没有VS的情况下使用记事本键入逻辑,可能会出现一些错误。
答案 1 :(得分:0)
如果您在project.json
中定义了两个目标框架(例如aspnetcore
和net451
),那么将创建两个单独的dll并将其放入lib/aspnetcore
和{{1}在nuget包里面。 Nuget将根据使用该软件包的项目的目标框架知道要使用哪个。
现在,您可以在库中使用lib/net451
语句来区分哪些代码部分应仅针对指定平台进行编译。
一个简单的例子:
#ifdef
要使这些开关工作,您必须在project.json中定义特定于框架的常量:
using System;
namespace MyLib
{
#if NETFX
using HttpContext = System.Web.HttpContext;
#elif NETCORE
using HttpContext = Microsoft.AspNetCore.Http.HttpContext;
#endif
public class MyClass
{
public string GetUserAgent(HttpContext ctx)
{
return ctx.Request.Headers["User-Agent"];
}
public void WriteToResponse(HttpContext ctx, string text)
{
#if NETFX
ctx.Response.Output.Write(text);
#elif NETCORE
var bytes = System.Text.Encoding.UTF8.GetBytes(text);
ctx.Response.Body.Write(bytes, 0, bytes.Length);
#endif
}
}
}
请注意,两个框架都有不同的依赖关系。编译为netcoreapp和net451时, "frameworks": {
"netcoreapp1.0": {
"buildOptions": {
"define": [
"NETCORE"
]
},
"dependencies": {
"Microsoft.NETCore.App": {
"type": "platform",
"version": "1.0.0"
},
"Microsoft.AspNetCore.Http": "1.0.0"
}
},
"net451": {
"buildOptions": {
"define": [
"NETFX"
]
},
"dependencies": {
"Microsoft.AspNet.WebApi": "5.2.3"
},
"frameworkAssemblies": {
"System.Web": "4.0.0.0"
}
}
},
这里将是一个不同的类型。幸运的是,这些类型具有非常相似的方法,因此通常可以以相同的方式使用它们,而不使用HttpContext
s(如#ifdef
中)。其他时候,你将无法避免它(如在GetUserAgent
中)。
现在,在AspNet Core项目中,你可以像这样使用这个库:
WriteToResponse
在旧的AspNet MVC中:
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.Use(async (ctx, next) => {
var lib = new MyLib.MyClass();
var msg = lib.GetUserAgent(ctx);
lib.WriteToResponse(ctx, "user agent is: " + msg);
});
}
github 上的完整源代码。
答案 2 :(得分:0)
答案是,这是不可能的。同样你不能创建一个NuGet包来同时定位MVC1和MVC2(两者都不是Nuget包可用)
当然,您可以使用装配绑定,但只有在没有更改的情况下才会使用。
Microsoft正在使用" AspNetCore"命名ASP.NET核心软件包,例如Microsoft.AspNetCore.Mvc vs Microsoft.AspNet.Mvc