Вопрос по project, nlog, dll, visual-studio-2012, c# – Настройка решения C # для нескольких проектов с использованием NLog в Visual Studio

10

Мое решение в Visual Studio 2012 в настоящее время содержит два проекта:

DLLПриложение WPF (для которого требуются методы DLL)

И DLL, и приложение WPF, используйтеNLog для регистрации. В настоящее время каждый проект содержитNLog Сама DLL.

Вот что я не делаюТ понять:

Мне кажется ненужным в том числе и идентичныйNLog DLL в каждом проекте.Однако DLL должна быть многократно использована в других решениях, т.е.NLog DLL должна содержаться в проекте DLL.

Каким будет адекватный способ настройки решения и / или проектов Visual Studio?

Оставь это, как сейчас, яскажу Там будет только одна копия DLL для каждой сборки, которая хочет ее использовать. Если исполняемая сборка, которая использует DLL, например, ссылается на две другие сборки библиотеки классов, которые также используют DLL, вы будетееще получите только одну DLL в выходной папке для исполняемой сборки. Matthew Watson

Ваш Ответ

3   ответа
7

которую вы планируете совместно использовать между различными проектами, возможно, было бы целесообразно добавить ссылку NLog и код оболочки только в эту библиотеку, а затем убедиться, что любое потребительское приложение (например, ваш проект WPF) имеет NLog. Файл .config, связанный с ним.

Так как тыиспользую VS2012 Iя предполагаю, что выТакже, скорее всего, вы работаете с .NET 4.5, который позволяет вам воспользоваться новыми атрибутами информации о вызывающем абоненте. Я'Мы написали следующий код ниже для базовой оболочки NLog и считаем, что он имеет идеальный баланс эффективности (неиспользовать StackTrace) и удобство использования.

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 name="exception">
        /// <param name="callerPath">
        /// <param name="callerMember">
        /// <param name="callerLine">
        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 name="exception">
        /// <param name="callerPath">
        /// <param name="callerMember">
        /// <param name="callerLine">
        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 name="exception">
        /// <param name="callerPath">
        /// <param name="callerMember">
        /// <param name="callerLine">
        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 name="exception">
        /// <param name="callerPath">
        /// <param name="callerMember">
        /// <param name="callerLine">
        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 name="exception">
        /// <param name="callerPath">
        /// <param name="callerMember">
        /// <param name="callerLine">
        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 name="exception">
        /// <param name="callerPath">
        /// <param name="callerMember">
        /// <param name="callerLine">
        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 name="message">
        /// <param name="exception">
        /// <param name="callerPath">
        /// <param name="callerMember">
        /// <param name="callerLine">
        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})
Почему установщик для Enabled использует цикл while для проверки текущего состояния Enabled? Wouldn»Разве достаточно просто вызвать LogManager.EnableLogging (), если значение равно true, и LogManager.DisableLogging () в противном случае? Scott Simontis
Можно также указать .net 4.0, если вы добавите ссылку на "Компоненты сборки Microsoft BCL " (через NuGet) Xilmiki
Только что обнаружил, что есть счетчик включения журнала и что Enable и Disable увеличивают или уменьшают этот счетчик соответственно. Я нахожу, что названия немного сбивают с толку, надеюсь, кто-то еще учится на этом. Scott Simontis
1

ии. Я описал это вэтот блог, Это'о log4net, но это тот же принцип, что бы вы ни использовали. В любом случае, вам нужна сборка журнала в каждом проекте, где вы ее используете, но абстрагируя ее,Его легко заменить чем-то другим (например, при тестировании). Ведение журнала - это инфраструктура, поэтому вы должны поместить интерфейсы и конкретную реализацию в проект инфраструктуры и сослаться на него из проектов, в которые вы хотите войти.

Это хорошо, и я согласен, но что, если DI не может быть реализован. Я хотел бы вести отдельный журнал и ссылаться на него в своем решении в нескольких проектах. JoshYates1980
9

вам жна DLL во всех проектах, где вы ее используете, и, конечно, вам жно, чтобы она была разверта вместе с исполняемыми файлами исполняемого файла (в вашем случае WPF-приложением), чтобы ее можно было найти и использовать во время выполнения.

Во всех моих проектах я обычно создаю оболочку вокруг механизма ведения журналов, чтобы мне не приходилось ссылаться и зависеть от определенных сторонних API-интерфейсов ведения журналов, таких как Log4Net или NLog, поэтому я везде использую свой класс ведения журналов оболочки, а затем иметь ссылку на сборку журнала только в классе оболочки 's проект и в исполняемом проекте, чтобы сборка была разверта в папку bin.

надеюсь это поможет ;-)

Похожие вопросы