Из библиотеки. NET как проверить, находится ли сборка / приложение RUNNING в сборке Debug (без присоединенного отладчика)? - PullRequest
0 голосов
/ 27 апреля 2020

Я делаю библиотеку классов Foo (Xamarin Android Библиотека, если уместно, но я предпочитаю общее решение. NET, если возможно), и мне нужно что-то вроде этого:

if (builtInDebugConfig) 
{
    this.DoSomething();
}

Теперь Foo.dll обязательно будет скомпилирован в режиме Release при вызове вышеуказанного кода. Поэтому #if точно не возможно, Conditional также не должно работать (поправьте меня, если я ошибаюсь, я прочитал, что это тоже атрибут компилятора) (ответ на вопрос и мой тест подтверждает Conditional работает). Самое близкое, о чем я могу подумать, это Debugger.IsAttached, однако большую часть времени мы тестируем приложения без подключенного отладчика.

Есть ли способ определить, является ли вызывающая сборка скомпилировано с DEBUG symbol / config? Если возможно, я не хочу, чтобы в вызывающем (app) коде было что-то подобное в каждом приложении, потому что оно игнорирует цель:

#if DEBUG
    Foo.IsDebug = true;
#endif

UPDATE: Разъяснение, почему я хочу этого: я хочу включить коды отладки (т.е. включить сигнал отладки WebView), если вызывающее приложение находится в разработке и не хочет, чтобы такой код существовал в окончательном виде. Вот почему меня интересует решение, предотвращающее утечку такого кода в сборку Release.

Ответы [ 2 ]

4 голосов
/ 27 апреля 2020

Вы можете использовать Conditional в Foo для украшения метода - любые вызовы этого метода будут зависеть от того, определяет ли код , вызывающий соответствующий символ. Так что-то вроде:

[Conditional("DEBUG")]
public void MaybeSetDebugMode()
{
    // Remember the decision
}

Тогда вызывающий код может безоговорочно написать код вызова MaybeSetDebugMode, и вызов будет только на самом деле скомпилирован, если DEBUG определено, когда вызывающий код скомпилирован. Сам метод в Foo будет скомпилирован в Foo.dll независимо от символов, определенных при его компиляции.

Это не то же самое, что #if, который зависит от символы при компиляции кода.

Обратите внимание, что именно так Debug.WriteLine и c работают.

Один недостаток: код Абсолютно будет существовать в "окончательной сборке", если вы не предпримете больше действий. Это связано с тем, что существование кода в Foo.dll не может измениться в зависимости от того, что его вызывает.

Так что вы можете на самом деле захотите использовать, например, #if :

#if FINAL_BUILD
public void MaybeSetDebugMode()
{
    // This method exists so that the calling code will still build
    // with the final DLL, but there won't be any "interesting" code
    // for anyone to find.
}

#else

public void MaybeSetDebugMode()
{
    // Interesting code goes here. This code won't be included in the final build,
    // but callers can call it unconditionally, because there'll be an empty
    // method in the final build.
}
#endif
0 голосов
/ 27 апреля 2020

Благодаря комментариям и ответам, я нашел два рабочих решения, оба великолепны, но я думаю, что я буду использовать Conditional в своем финальном проекте. IsExecutingDebug проверяет, присутствует ли DebuggableAttribute в сборке Entry, а Conditional объясняется в ответе Джона Скита .

namespace ClassLibrary1
{
    public class Class1
    {

        public bool IsExecutingDebug()
        {
#if DEBUG
            Console.WriteLine("Debug in lib");
#endif

            return Assembly.GetExecutingAssembly().IsInDebug();
        }

        [Conditional("DEBUG")]
        public void ExecuteInDebugOnly()
        {
            Console.WriteLine("Hi!");
        }

    }
}

namespace System
{

    public static class MyExtensions
    {
        public static bool IsInDebug(this Assembly assembly)
        {
            return assembly.GetCustomAttributes<DebuggableAttribute>().Any();
        }
    }

}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...