Recently I started to study Xamarin and today I opened big project written on MvvmCross, and I have to add new features there. That is difficult as usually I work with Java and Android Studio, but now I have to deep in C# and Visual Studio.
Firstly I want to understand the flow of this project and for this I want to insert logs in different .cs classes and see them while navigate through the app.
In Setup.cs:
protected override IMvxTrace CreateDebugTrace()
{
return new NLogTrace();
}
NLogTrace.cs:
public class NLogTrace : IMvxTrace
{
private readonly ILogger _logger;
public NLogTrace()
{
InitializeNLog();
_logger = LogManager.GetLogger("MvvmCross");
}
public static string LogFileName => Path.Combine(GetCacheFolder(), "logFile.txt");
private static void InitializeNLog()
{
// Step 1. Create configuration object
var config = new LoggingConfiguration();
// Step 2. Create targets and add them to the configuration
var consoleTarget = new ConsoleTarget();
config.AddTarget("console", consoleTarget);
var logFolderPath = GetCacheFolder();
var fileTarget = new FileTarget
{
FileName = Path.Combine(logFolderPath, "logFile.txt"),
ArchiveFileName = Path.Combine(logFolderPath, "log.{#}.txt"),
ArchiveEvery = FileArchivePeriod.Day,
ArchiveNumbering = ArchiveNumberingMode.Date,
MaxArchiveFiles = 7
};
config.AddTarget("file", fileTarget);
// Step 3. Set target properties
consoleTarget.Layout = @"${longdate}|${level:uppercase=true}|${logger}|${message}"; //
fileTarget.Layout = "${longdate}|${level:uppercase=true}|${logger}|${message}";
// Step 4. Define rules
var rule1 = new LoggingRule("*", LogLevel.Trace, consoleTarget);
config.LoggingRules.Add(rule1);
#if DEBUG
var rule2 = new LoggingRule("*", LogLevel.Debug, fileTarget);
config.LoggingRules.Add(rule2);
#else
var rule2 = new LoggingRule("*", LogLevel.Info, fileTarget);
config.LoggingRules.Add(rule2);
#endif
LogManager.Configuration = config;
}
private static string GetCacheFolder()
{
var documents = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
var relativeCacheFolderPath = Path.Combine(documents, "Storage", "Logs");
var directory = new DirectoryInfo(relativeCacheFolderPath);
var resolvedCacheFolderPath = directory.FullName;
return resolvedCacheFolderPath;
}
public void Trace(MvxTraceLevel level, string tag, string message)
{
switch (level)
{
case MvxTraceLevel.Diagnostic:
_logger.Debug(message);
break;
case MvxTraceLevel.Warning:
_logger.Warn(message);
break;
case MvxTraceLevel.Error:
_logger.Error(message);
break;
}
}
public void Trace(MvxTraceLevel level, string tag, Func<string> message)
{
switch (level)
{
case MvxTraceLevel.Diagnostic:
_logger.Debug(message());
break;
case MvxTraceLevel.Warning:
_logger.Warn(message());
break;
case MvxTraceLevel.Error:
_logger.Error(message());
break;
}
}
public void Trace(MvxTraceLevel level, string tag, string message, params object[] args)
{
switch (level)
{
case MvxTraceLevel.Diagnostic:
_logger.Debug(message, args);
break;
case MvxTraceLevel.Warning:
_logger.Warn(message, args);
break;
case MvxTraceLevel.Error:
_logger.Error(message, args);
break;
}
}
}
So, I see some logger but I don't have any idea how to use it in some .cs file. Can you provide some snippet how to use
Trace(MvxTraceLevel level, string tag, string message)
in arbitrarily chosen .cs file from .Core or .Droid projects?
You have to utilize Dependency injection. For complete documentation see docs. In short, you add a IMvxLog
parameter in your view model/service constructor:
public MyViewModel( IMvxLog logger )
{
this._logger = logger;
}
And then just call appropriate method on _logger
:
_log.Trace("Some message");
If you want to use IMvxLog
from a class where you cannot setup dependency injection, you can use Mvx
to resolve it:
var logger = Mvx.Resolve<IMvxLog>();