【问题标题】:managing static data within WCF在 WCF 中管理静态数据
【发布时间】:2014-02-05 15:56:20
【问题描述】:

我正在使用在项目之间共享的库中具有静态日志记录对象的解决方案。这是它的结构:

public class AppLog
{
  private static string _logFile;
  private static string _appName;

  public static string AppName
  { 
    get { return _appName; }
    set 
    {
      _appName = value;
      InitLogFilePath(); // initializes _logFile according to _appName
    }
  }

  public static Write(string msg) 
  {
    // writes to _logFile
  }
}

它适用于各种 Windows 应用程序和 Windows 服务:它们可以在启动时初始化 AppLog.AppName,并且可以在整个代码中调用 AppLog.Write。共享模块写入一个根据AppName的初始化命名的文件。

我遇到的问题是在 WCF Web 服务中使用它。 Web 服务配置为InstanceContextMode.PerCallAppLog.AppName 正在根据 ServiceHostBase.Description.Name 进行初始化。但是由于多个 Web 服务在同一个 AppDomain 中运行,所以这个静态数据是共享的。所以一个 ws 调用设置了AppLog.AppName,它被下一个调用更改,可能有不同的ServiceHostBase.Description.Name

如何对其进行重组,以便AppLog.Write 仍然可以在我的解决方案中的整个项目中使用,但对每个 Web 服务的命名处理方式不同?

如果可以判断代码是否在 Web 服务中运行,并且如果我可以检索服务的 ServiceHostBase.Description,那么我可以维护对适当文件名的查找。但是我还没有找到方法来做到这一点。

【问题讨论】:

    标签: c# .net wcf static


    【解决方案1】:

    鉴于您的日志记录的结​​构方式,没有一个好的解决方案。

    大多数日志库的结构都是为了让您创建记录器的实例,将任何特定于应用程序的数据(如 AppName)传递给该实例,然后将该实例存储在私有静态成员中。静态存储在应用程序中,而不是日志库中。这避免了您所拥有的共享冲突,并且仍然只创建少量固定数量的记录器实例。

    为了说明这一点,这里有一个来自CodeProject log4net tutorial 的标准log4net 示例。此代码将当前类名传递给记录器的实例。

    private static readonly log4net.ILog log = log4net.LogManager.GetLogger
        (System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
    

    我的建议是考虑更改为 log4net 或 NuGet 上可用的任何其他日志记录包。

    【讨论】:

      【解决方案2】:

      鉴于您的情况,AppName 不应该在哪里。您需要一个包含 AppName 并将核心“写入”逻辑向下传递到当前 AppLog 的 per-webservice 日志记录外观。然后每个 Web 服务都有自己的 LogFacade 实例。

      class LogFacade
      {
        public string AppName {get; private set;}
      
        LogFacade(string appName)
        {
          AppName = appName;
        }
      
        public void Write(string msg) 
        {
          AppLog.Write(string.format("[{0}]{1}", AppName, msg));
        }
      }
      

      或者正如 ErnieL 所说,看看 log4net。

      【讨论】:

      • 关于 log4net:我现在不能引入新的库/依赖项。查看您提供的示例代码,我认为这行不通:AppName 需要一个实例,而 Write 是一个静态方法。
      • @jltrem,是的,你是对的。我只是复制了您的 AppLog。 Write 和 AppName 在实例或静态方面应保持一致。
      • 好的,所以我的问题仍然存在:从不同的程序集调用它时,如何确定 LogFacade 的正确实例?如果我可以识别我是否在 Web 服务中运行,如果是,那么我可以识别记录器实例。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-09-21
      • 1970-01-01
      • 2014-07-13
      • 1970-01-01
      • 2021-01-06
      • 1970-01-01
      • 2013-01-11
      相关资源
      最近更新 更多