Nlog: Using NLog in Xamarin.Forms (Portable) project

Created on 29 Apr 2016  路  9Comments  路  Source: NLog/NLog

Type: Question
NLog version: 4.4.0-beta5 / 4.3.3
Platform: Xamarin PCL (.Net 4.5)

I tried to install the latest alpha release in my PCL project (Xamarin.iOS, Xamarin.Droid, UWP) with this command:

Install-Package NLog -Pre

Thereby I'm using Visual Studio 2015. The installation fails with this error

Install-Package : Could not install package 'System.Diagnostics.Contracts 4.0.1-beta-23516'. You are trying to install this package into a project that targets
'MonoAndroid,Version=v6.0', but the package does not contain any assembly references or content files that are compatible with that framework. For more
information, contact the package author.
At line:1 char:1

  • Install-Package NLog -Pre
  • ~~~~~

    • CategoryInfo : NotSpecified: (:) [Install-Package], Exception

    • FullyQualifiedErrorId : NuGetCmdletUnhandledException,NuGet.PackageManagement.PowerShellCmdlets.InstallPackageCommand

If I try to install NLog 4.3.3 I get this error:

Error Could not install package 'NLog 4.3.3'. You are trying to install this package into a project that targets '.NETPortable,Version=v4.5,Profile=Profile111', but the package does not contain any assembly references or content files that are compatible with that framework. For more information, contact the package author. 0

Is it possible to integrate NLog in my project and if yes, how?

Another question: Will support for UWP be included in NLog 4.4?

Thanks!

Edit:
What I've found out is that I can only install NLog directly in the Xamarin.iOS and Xamarin.Droid sub-projects.

Additional question: Where do you instantiate the logger? In a global singleton?

question

Most helpful comment

My solution has been to make interfaces in my PCL that duplicate ILogger and LogManager, then to create a shared project (not a PCL) with implementations of those. See this gist for the code.

For instantiation, the Application object for my Xamarin.Forms app has a static property holding the ILogManager, and the first thing the platform specific Main function does is initialize NLog (at least on iOS, initialization must be done in code to get the correct path if you're using the documents folder) then set Application.LogManager. To create loggers for each class I use a slight variation on the normal pattern. The lazy initialization may not be strictly necessary, I just wanted to be sure no loggers got created before Application.LogManager had been set.

public class MyClass
{
  // Note this is my ILogger, not NLog.ILogger
  private static readonly Lazy<ILogger> __log = 
    new Lazy<ILogger>(() => Application.LogManager.GetLogger<MyClass>());
  private static ILogger Log { get { return __log.Value; } }
}

What I'd really like to see, is the interface components of NLog (ILogger, LogLevel, an interface for LogFactory, etc) split out into a separate library. For most people it wouldn't affect anything - adding NLog would just automatically pull in the NLog.Interfaces dependency (or whatever it's called). However, people who want to log in PCLs can add only the Interfaces, and all they have to worry about is injecting the correct LogFactory from platform specific code. @304NotModified do you have any objections to that or thoughts about implementing it?

All 9 comments

We have the same issue with UWP. There are packages, but some are empty which is really unclear how to fix (and which packages).

Additional question: Where do you instantiate the logger? In a global singleton?

https://github.com/NLog/NLog/blob/master/src/NLog/LogFactory.cs

My solution has been to make interfaces in my PCL that duplicate ILogger and LogManager, then to create a shared project (not a PCL) with implementations of those. See this gist for the code.

For instantiation, the Application object for my Xamarin.Forms app has a static property holding the ILogManager, and the first thing the platform specific Main function does is initialize NLog (at least on iOS, initialization must be done in code to get the correct path if you're using the documents folder) then set Application.LogManager. To create loggers for each class I use a slight variation on the normal pattern. The lazy initialization may not be strictly necessary, I just wanted to be sure no loggers got created before Application.LogManager had been set.

public class MyClass
{
  // Note this is my ILogger, not NLog.ILogger
  private static readonly Lazy<ILogger> __log = 
    new Lazy<ILogger>(() => Application.LogManager.GetLogger<MyClass>());
  private static ILogger Log { get { return __log.Value; } }
}

What I'd really like to see, is the interface components of NLog (ILogger, LogLevel, an interface for LogFactory, etc) split out into a separate library. For most people it wouldn't affect anything - adding NLog would just automatically pull in the NLog.Interfaces dependency (or whatever it's called). However, people who want to log in PCLs can add only the Interfaces, and all they have to worry about is injecting the correct LogFactory from platform specific code. @304NotModified do you have any objections to that or thoughts about implementing it?

What I'd really like to see, is the interface components of NLog (ILogger, LogLevel, an interface for LogFactory, etc) split out into a separate library.

So a package called like NLog.Abstractions?

I think it's a breaking change. We can do it for NLog 5, but I think it's too soon to NLog 5 (and a lot has to be done before it)

@304NotModified yes, that exactly.

I just tried the latest NLog nuget v4.4.0-beta11 on a new Xamarin.Forms project, that had its XF updated to v2.2.
it did not succeed:

Could not install package 'NLog 4.4.0-beta11'. You are trying to install this package into a project that targets '.NETPortable,Version=v4.5,Profile=Profile111', but the package does not contain any assembly references or content files that are compatible with that framework. For more information, contact the package author.

so no references were added to any of the default project ".Driod, .iOS, UWP, Windows 8.1".

Don't get it. Netstandard1.3 should be UWP/Mono compatible :(

https://github.com/dotnet/corefx/blob/master/Documentation/architecture/net-platform-standard.md

Can you try without windows 8.1?

Ow yes, that's also the problem in the TS. Xamarin.Ios/android works, but isn't portable.

Not sure if a portable for xamarin ios+android +uwp solves it.

closing this, feature request is at #155

Was this page helpful?
0 / 5 - 0 ratings

Related issues

sszost picture sszost  路  3Comments

BobSeu picture BobSeu  路  3Comments

JustArchi picture JustArchi  路  3Comments

npandrei picture npandrei  路  3Comments

MaximRouiller picture MaximRouiller  路  3Comments