Logging is an essential part of almost every application. However, when writing a PRISM app for WPF, it’s hard to find documentation on how to exactly register logging with your IoC Container. In this post we will add logging (using Serilog and Microsoft Logging Abstractions) to either DryIoC or Unity. This approach will work from PRISM 7 upwards.

Necessary Nuget Packages

You first have to add the following NuGet packages to your startup project (the one containing App.xaml and App.xaml.cs):

Also you need packages for your logging framework of choice, we will use Serilog in this example, so include

However you can easily replace this with nLog or any other logging framework.

And in order to add the IServiceCollection to your IOC Container you need

Registering Logging with the Container

To register the logging framework with the IoC Container, add the following override to the App.xaml.cs and import all relevant usings from the previously added nuget packages:

DryIoC

protected override IContainerExtension CreateContainerExtension()
{
    var serviceCollection = new ServiceCollection();
    serviceCollection.AddLogging(loggingBuilder =>
        loggingBuilder.AddSerilog(dispose: true));

    return new DryIocContainerExtension(new Container(CreateContainerRules())
        .WithDependencyInjectionAdapter(serviceCollection));
}

Here we first create the ServiceCollection which makes it incredibly easy to add logging,by calling… AddLogging()! This is also the place to add another Logging Framework if you prefer nlog or log4net or setup the minimal logging level etc.

Then we have to make sure that the services registered with the ServiceCollection are also registered in the DryIoC Container used in the rest of the application. For this we use the WithDependencyInjectionAdapter extension method, found in DryIoc.Microsoft.DependencyInjection .

Unity

protected override IContainerExtension CreateContainerExtension()
{
    var serviceCollection = new ServiceCollection();
    serviceCollection.AddLogging(loggingBuilder =>
        loggingBuilder.AddSerilog(dispose: true));

    var container = new UnityContainer();
    container.BuildServiceProvider(serviceCollection);

    return new UnityContainerExtension(container);
}

The code is almost the same as in the DryIoC case, but Unity.Microsoft.DependencyInjection works slighlty different, thus you have to call BuildServiceProvider.

Configuring the Logger

Configure the logger before the Shell is created, by e.g. adding the following code to CreateShell:

protected override Window CreateShell()
{
    Log.Logger = new LoggerConfiguration()
        .Enrich.FromLogContext()
        .WriteTo.Debug()
        .CreateLogger();

    return Container.Resolve<MainWindow>();
}

This is just a basic configuration, more info can be found on the project page. In order to be able to use Debug as a sink you need Serilog.Sinks.Debug.

Using the logger

In your services you can now inject the generic ILogger, e.g.

public class MyService : IMyService
{
    public MyService(ILogger<MyService> logger)
    {
        logger.LogInformation("Hello World from your logger!");
    }
}

Happy Logging!