管理WCF中的静态数据

时间:2014-02-05 15:56:20

标签: c# .net wcf static

我正在一个解决方案中工作,该解决方案在项目中共享的库中具有静态日志记录对象。这是它的结构:

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.PerCall。根据{{​​1}}初始化AppLog.AppName。但由于多个Web服务在同一AppDomain中运行,因此共享此静态数据。因此,一个ws会调用ServiceHostBase.Description.Name集,并且会在下一个调用时更改,这可能会有不同的AppLog.AppName

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

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

2 个答案:

答案 0 :(得分:0)

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

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

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

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

我的建议是查看更改为log4net或NuGet上可用的任何其他日志包。

答案 1 :(得分:0)

根据您的情况,AppName不应该在哪里。您需要一个包含AppName的per-webservice日志记录外观,并将核心“Write”逻辑传递给您当前的AppLog。然后,每个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。