设置在Visual Studio中使用NLOG多个项目C#解决方案(Setting up C# so

2019-08-17 12:31发布

我在Visual Studio解决方案目前2012包含两个项目:

  • DLL
  • WPF应用程序(这需要DLL的方法)

这两个,DLL和WPF应用程序,使用NLog用于记录。 目前,每个项目包含NLog DLL本身。

以下是我不明白:

  1. 它似乎没有必要对我来说,包括相同的NLog在每个项目中的DLL。
  2. 然而,DLL应在其他的解决方案,即在某种程度上可重复使用的NLog DLL必须包含在DLL项目。

什么是建立在Visual Studio解决方案和/或项目的适当方法是什么?

Answer 1:

那么你需要在你使用它,你一定需要它部署的可执行文件(在你的情况WPF应用程序)的二进制文件,以便它可以被发现并在运行时使用的所有项目的DLL。

我倾向于在我所有的项目做的是创建一个围绕日志引擎的包装,这样我就不需要参考,并依赖于特定的第三方日志记录API,像log4net的或NLOG,所以我到处,然后我用我的包装日志类有一个参考asembly只在包装类的项目,并在项目执行记录有部署到bin文件夹中的程序集。

希望这可以帮助 ;-)



Answer 2:

如果你的DLL就是你打算在各个项目之间共享一个核心库,它可能是明智的添加NLOG参考和包装代码只是该库,然后确保任何消费者应用程序(如您的WPF项目)具有NLOG的.config与它相关的文件。

由于您使用VS2012我假设你也最有可能与.NET 4.5,它允许你采取新的来电者信息属性的优势合作。 我已经写了下面的下面的代码为基础NLOG包装,并相信它有效率(不使用堆栈跟踪)和可用性的完美平衡。

using System;
using System.Runtime.CompilerServices;
using NLog;

namespace ProjectName.Core.Utilities
{
    /// <summary>
    /// Generic NLog wrapper.
    /// </summary>
    public static class Logger
    {
        /// <summary>
        /// Gets or sets the enabled status of the logger.
        /// </summary>
        public static bool Enabled
        {
            get { return LogManager.IsLoggingEnabled(); }
            set
            {
                if (value)
                {                    
                    while (!Enabled) LogManager.EnableLogging();
                }
                else
                {
                    while (Enabled) LogManager.DisableLogging();
                }
            }
        }

        /// <summary>
        /// Writes the diagnostic message at the Trace level.
        /// </summary>
        /// <param name="message"></param>
        /// <param name="exception"></param>
        /// <param name="callerPath"></param>
        /// <param name="callerMember"></param>
        /// <param name="callerLine"></param>
        public static void Trace(string message, Exception exception = null,
            [CallerFilePath] string callerPath = "",
            [CallerMemberName] string callerMember = "",
            [CallerLineNumber] int callerLine = 0)
        {
            Log(LogLevel.Trace, message, exception, callerPath, callerMember, callerLine);
        }

        /// <summary>
        /// Writes the diagnostic message at the Debug level.
        /// </summary>
        /// <param name="message"></param>
        /// <param name="exception"></param>
        /// <param name="callerPath"></param>
        /// <param name="callerMember"></param>
        /// <param name="callerLine"></param>
        public static void Debug(string message, Exception exception = null,
            [CallerFilePathAttribute] string callerPath = "",
            [CallerMemberName] string callerMember = "",
            [CallerLineNumber] int callerLine = 0)
        {
            Log(LogLevel.Debug, message, exception, callerPath, callerMember, callerLine);
        }

        /// <summary>
        /// Writes the diagnostic message at the Info level.
        /// </summary>
        /// <param name="message"></param>
        /// <param name="exception"></param>
        /// <param name="callerPath"></param>
        /// <param name="callerMember"></param>
        /// <param name="callerLine"></param>
        public static void Info(string message, Exception exception = null,
            [CallerFilePathAttribute] string callerPath = "",
            [CallerMemberName] string callerMember = "",
            [CallerLineNumber] int callerLine = 0)
        {
            Log(LogLevel.Info, message, exception, callerPath, callerMember, callerLine);
        }

        /// <summary>
        /// Writes the diagnostic message at the Warn level.
        /// </summary>
        /// <param name="message"></param>
        /// <param name="exception"></param>
        /// <param name="callerPath"></param>
        /// <param name="callerMember"></param>
        /// <param name="callerLine"></param>
        public static void Warn(string message, Exception exception = null,
            [CallerFilePathAttribute] string callerPath = "",
            [CallerMemberName] string callerMember = "",
            [CallerLineNumber] int callerLine = 0)
        {
            Log(LogLevel.Warn, message, exception, callerPath, callerMember, callerLine);
        }

        /// <summary>
        /// Writes the diagnostic message at the Error level.
        /// </summary>
        /// <param name="message"></param>
        /// <param name="exception"></param>
        /// <param name="callerPath"></param>
        /// <param name="callerMember"></param>
        /// <param name="callerLine"></param>
        public static void Error(string message, Exception exception = null,
            [CallerFilePathAttribute] string callerPath = "",
            [CallerMemberName] string callerMember = "",
            [CallerLineNumber] int callerLine = 0)
        {
            Log(LogLevel.Error, message, exception, callerPath, callerMember, callerLine);
        }

        /// <summary>
        /// Writes the diagnostic message at the Fatal level.
        /// </summary>
        /// <param name="message"></param>
        /// <param name="exception"></param>
        /// <param name="callerPath"></param>
        /// <param name="callerMember"></param>
        /// <param name="callerLine"></param>
        public static void Fatal(string message, Exception exception = null,
            [CallerFilePathAttribute] string callerPath = "",
            [CallerMemberName] string callerMember = "",
            [CallerLineNumber] int callerLine = 0)
        {            
            Log(LogLevel.Fatal, message, exception, callerPath, callerMember, callerLine);
        }

        /// <summary>
        /// Writes the specified diagnostic message.
        /// </summary>
        /// <param name="level"></param>
        /// <param name="message"></param>
        /// <param name="exception"></param>
        /// <param name="callerPath"></param>
        /// <param name="callerMember"></param>
        /// <param name="callerLine"></param>
        private static void Log(LogLevel level, string message, Exception exception = null, string callerPath = "", string callerMember = "", int callerLine = 0)
        {
            // get the source-file-specific logger
            var logger = LogManager.GetLogger(callerPath);

            // quit processing any further if not enabled for the requested logging level
            if (!logger.IsEnabled(level)) return;

            // log the event with caller information bound to it
            var logEvent = new LogEventInfo(level, callerPath, message) {Exception = exception};
            logEvent.Properties.Add("callerpath", callerPath);
            logEvent.Properties.Add("callermember", callerMember);
            logEvent.Properties.Add("callerline", callerLine);
            logger.Log(logEvent);
        }
    }
}

然后尝试投掷到这个目标的一个布局领域在NLog.config抢到了详细的来电信息。

${event-context:item=callerpath}:${event-context:item=callermember}(${event-context:item=callerline})


Answer 3:

你最好抽象的使用日志记录机制。 我在此说明本博客文章 ,它是关于log4net的,但无论您使用的框架同样的原则。 在任何情况下,你需要在你使用的每个项目的日志组件,但它抽象很容易被其他的东西(例如测试时)来代替它。 日志为基础,所以你会投入基础设施项目的接口和具体落实,并说明一个从项目中要记录。



文章来源: Setting up C# solution with multiple projects using NLog in Visual Studio