我们有几个用.Net Framework编写的网站。 现在我们要转到.Net Core。 我们希望一个接一个地做,因此旧网站和新网站应该并存。 所有网站共享通用的dll,例如LoggerDll。
为了在两个网站(旧网站和新网站)中仅使用一个dll,我们将LoggerDll更改为.Net Standard,并从两个网站中添加对它的引用。
问题在于LoggerDll引用System.Web dll是为了获取用于写入日志的请求的IP(以及其他请求信息),而.Net Core中不存在。
例如:
public void WriteToLog(string message)
{
//This line doesn't compile in .Net Core
string userIp = System.Web.HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"];
WriteToDB(message, userIp);
}
我不想将IP作为参数传递给WriteToLog,因为那样的话,我需要将其作为参数添加到所有调用它的方法中,并且在发生异常时几乎所有方法都调用WriteToLog。
所以我宁愿继续从某些“全局”对象获取请求信息,但应在.Net Core和.Net Framework中进行编译。
我想创建一个新类“ MyRequestInfo”,为其创建一个静态属性,然后在“ BeginRequest”事件中用数据填充它。
例如:
public class MyRequestInfo
{
public string UserIp { get; set; }
}
public class MyRequest
{
[ThreadStatic] \\ Is ThreadStatic is ok?
public static MyRequestInfo ReqInfo { get; set; }
}
//Global.asax
protected void Application_BeginRequest(object sender, EventArgs e)
{
MyRequest.ReqInfo.UserIp = System.Web.HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"];
}
//LoggerDll
public void WriteToLog(string message)
{
string userIp = MyRequest.ReqInfo.UserIp;
WriteToDB(message, userIp);
}
谢谢
答案 0 :(得分:0)
这个灵魂还可以吗?
您的解决方案将无法与async/await
一起使用,因为两个不同的线程可以在那里参与,并且[ThreadStatic]
属性将不会在异步流中持久保存值。
我应该使用AsynLocal还是其他?
我不知道如何使用AsynLocal
来实现它。
这是一个基本的想法:
LoggerDll
public static Func<string> UserIpGetter;
public void WriteToLog(string message)
{
string userIp = UserIpGetter();
WriteToDB(message, userIp);
}
Asp.Net
//Global.asax
static string GetUserIp()
{
return System.Web.HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"];
}
protected void Application_Start(object sender, EventArgs e)
{
LoggerDll.UserIpGetter = GetUserIp;
}
Asp.Net Core
Startup.cs
public class Startup
{
static IServiceProvider _serviceProvider;
static string GetUserIp()
{
return _serviceProvider.GetService<IHttpContextAccessor>()
.HttpContext.Connection.RemoteIpAddress.ToString();
}
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddHttpContextAccessor();
...
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
_serviceProvider = app.ApplicationServices;
LoggerDll.UserIpGetter = GetUserIp;
...
}
}
要改进此代码,您可以声明:interface IUserIpGetter {string GetUserIp();}
,在Asp.Net
中编写一个实现,在Asp.Net Core
中编写另一个,在DI中注册并将它们注入LoggerDll.ctor
>