0

可能重复:
.NET NUnit 测试 - Assembly.GetEntryAssembly() 为空

我正在写一个日志库。默认情况下,我希望库写入为应用程序命名的公共应用程序数据文件夹中的目录。例如,如果应用程序名为“MyApplication.exe”,我希望将数据保存在“C:\ProgramData\MyApplication”中。

我正在使用此代码来构造路径:

   private static string loggingDataPath = 
      Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData) +
      Path.DirectorySeparatorChar + 
      Path.GetFileNameWithoutExtension(Assembly.GetEntryAssembly().CodeBase) +
      Path.DirectorySeparatorChar;

这完全符合预期,但有一个问题。我无法对库进行单元测试!

当我尝试运行单元测试时,它们都因 System.NullReferenceException 而失败。如果我用字符串替换“Assembly.GetEntryAssembly().CodeBase”调用,单元测试将再次正常运行。

我想我理解为什么会发生这种情况,但我不知道如何解决这个问题。我希望有人能够让我走上正义的道路。

蒂亚!

更新 (5-24-12):我不想对“loggingDataPath”的内容进行单元测试。仅存在“Assembly.GetEntryAssembly().CodeBase”调用会导致所有单元测试因上述异常而失败。请注意,“loggingDataPath”是静态的(因为它必须是静态库)。

4

2 回答 2

4

不仅仅是单元测试会导致问题。

鉴于GetEntryAssembly() 可以在从非托管应用程序加载托管程序集时返回 null并且CodeBase 可以包含从 Internet 下载的程序集的 URL,并且没有为从 GAC 加载的程序集设置,我会避免尝试这个通用日志库的方法。

如果这还不足以说服您,其他问题是 (a) 非特权用户将没有对 CommonApplicationData 的写入权限,以及 (b) 尝试写入同一个日志文件的应用程序的多个实例将是一个问题。

相反,我会在配置中定义日志文件的位置。

你会建议我把它放在哪里以避免这个问题?

正如我所说,我会在配置中定义它(例如 app.config 中的 appSetting)。这是最灵活的。如果你想把它放在 CommonApplicationData 下,你可以使用一个环境变量,当你Environment.ExpandEnvironmentVariables从配置文件中读取时,你可以使用该方法扩展它。例如:

<appSettings>
    <add key="logFile" value="%ALLUSERSPROFILE%\MyApp\MyLogFile.log" />
    ...
</appSettings>

您仍然必须解决授予非特权用户访问权限的问题,并避免从多个实例访问时发生争用。您说您的底层日志库支持并发访问,但请注意,这将产生潜在的性能成本,具体取决于您的日志记录的详细程度。

于 2012-05-24T13:50:41.083 回答
0

忽略先前答案的明智建议并仅解决我的问题,这是我解决问题的方法:

   public static string LoggingDataPath { 
      get { 
         return loggingDataPath.Length > 0 ? loggingDataPath : 
         Environment.GetFolderPath(Environment.SpecialFolder.CommonDocuments) + 
         Path.DirectorySeparatorChar + 
         Path.GetFileNameWithoutExtension(Assembly.GetEntryAssembly().CodeBase) + 
         Path.DirectorySeparatorChar; 
      } 

      set { loggingDataPath = value; } 
   } 

此解决方案避免在首次访问静态类时初始化“loggingDataPath”,从而避免调用“Assembly.GetEntryAssembly().CodeBase”。

于 2012-05-28T19:25:58.657 回答