I've created a .NET Core 3.1 project using a Host, the IoC container with IServiceCollection and implemented logging allover the place using the ILogger<T> interface from Microsoft.Extensions.Logging. I now need to implement more advanced logging and decided to use Serilog.
I assumed that it would be a breeze to switch from .NET built-in loggers to Serilog. But to my surprise, Serilog is using it's own ILogger interface - bummer! So now I needed to update ALL places to use Serilog ILogger, or to implement Serilog with a .NET Core ILogger<T> interface.
My question is - is it really not possible to use Serilog with the ILogger interface in Microsoft.Extensions.Logging? Would be so much smarter!
In the Serilog.Extensions.Logging assembly there is a extension method on IloggingBuilder called AddSerilog (it's in the Serilog namespace) that will allow you to use Serilog for logging. For example:
.NET Core 2.2 and earlier (using WebHost):
WebHost.CreateDefaultBuilder(args)
.ConfigureLogging(logging =>
{
logging.ClearProviders();
logging.AddSerilog();
});
.NET Core 3.1 and later (using generic Host for either web or console apps):
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder => webBuilder.UseStartup<Startup>()})
.UseSerilog();
Now the ILogger and ILogger<> implementation will call into Serilog.
For .NET 6 and later
using Serilog;
var builder = WebApplication.CreateBuilder(args);
builder.Host.UseSerilog((ctx, lc) => lc
.WriteTo.Console()
.ReadFrom.Configuration(ctx.Configuration));
Reference: Here
Related
I have a .Net Core 3.1 project that uses Serilog and posts messages to Azure Eventhub.
The problems started when we moved it to .Net 5.
Here's how it's configured
in Startup.cs
in ConfigureServices we have section
var eventHubConfig = Configuration.GetSection("Logging").GetSection("eventHub");
string eventHubConnection = eventHubConfig.GetValue<string>("connectionString");
Log.Logger = new LoggerConfiguration()
.WriteTo.AzureEventHub(new JsonFormatter(),
eventHubConnection.Replace(#"\", ""),
eventHubConfig.GetValue<string>("entityName"))
.CreateLogger();
in Configure method we have: loggerFactory.AddSerilog();
and in Program.cs
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseSerilog()
.UseStartup<Startup>();
Very simple and it's working for .Net Core 3.1, but once I change the target framework for the project to .Net 5 it stops working.
Any thoughts?
Has anyone seen the same issue?
Serilog uses an old version of Microsoft.Azure.EventHubs internally
I had the same issue and bumping to 4.3.2 solved the problem
Since then Microsoft.Azure.EventHubs have been deprecated and we have moved to Serilog 6 and Azure.Messaging.EventHubs
I am wondering is, since I would like to implement dependency injection container for my web application (MVC) controllers. In .NET Core framework, I used to have a Startup.cs file inside the project which was used for adding transients and dependency injections to the container, also for DbContext:
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
public void ConfigureServices(IServiceCollection services)
{
services.Configure<CookiePolicyOptions>(options =>
{
options.CheckConsentNeeded = context => true;
options.MinimumSameSitePolicy = SameSiteMode.None;
});
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
services.AddDbContext<LibraryContext>();
services.AddTransient<IGetBooksCommand, EfGetBooksCommand>();
}
I would like to know how could I achieve this in the full .NET Framework.
Prior to .Net Core, there is no built-in support for dependency injection the only way to get it was through the use of third-party frameworks such as Autofac, Castle Windsor, Unity, Ninject ..etc
You can check any of these frameworks and use them in your project.
.Net core Mvc supports built in dependency injection and it is capable of injecting dependencies in the controllers. So dependency registered as below can be used in controller
services.AddTransient<IGetBooksCommand, EfGetBooksCommand>();
However built in dependency injection functionality can be replaced by more mature DI frameworks. And that is very simple as below is the example for using Autofac
public IServiceProvider ConfigureServices(IServiceCollection services) {
var builder = new ContainerBuilder();
builder.Populate(services);
builder.RegisterType<EfGetBooksCommand>().As<IGetBooksCommand>();
var container = builder.Build();
return new AutofacServiceProvider(container);
}
ConfigureServices method now returns IServiceProvider instead of void. And dependencies will now be resolved using Autofac.
ref :
Dependency injection into controllers in ASP.NET Core
.Net Core Dependency Injection
I've updated my project from .net core 2.1 to 2.2 and then logging.AddAzureWebAppDiagnostics() in Program.cs no longer works.
public static IWebHost BuildWebHost(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.ConfigureLogging((hostingContext, logging) =>
{
logging.AddAzureWebAppDiagnostics();
})
.UseStartup<Startup>()
.Build();
}
'ILoggingBuilder' does not contain a definition for 'AddAzureWebAppDiagnostics' and no accessible extension method 'AddAzureWebAppDiagnostics' accepting a first argument of type 'ILoggingBuilder' could be found (are you missing a using directive or an assembly reference?
Referring to this document,
If targeting .NET Framework or referencing the Microsoft.AspNetCore.App metapackage, add the provider package to the project. Invoke AddAzureWebAppDiagnostics on an ILoggerFactory instance:
So the way might be slightly different from the previous one. How do I fix this issue?
The documentation is a bit tricky but if read carefully it become clear that following steps should be undertaken (for NET Core):
Microsoft.Extensions.Logging.AzureAppServices should be installed
There is NO need to call logging.AddAzureWebAppDiagnostics();
Logging can be configured using following code
// file startup.cs
using Microsoft.Extensions.Logging.AzureAppServices;
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
//...
services.Configure<AzureFileLoggerOptions>(Configuration.GetSection("AzureLogging"));
}
}
File appsettings.json should contain
"AzureLogging": {
"FileName" : "azure-diagnostics-",
"FileSizeLimit": 50024,
"RetainedFileCountLimit": 5
}
Logging should be turned on on Azure Portal. After enabling, Azure Portal may ask for installing addon. Message requiring to install addon will appear on logging config page.
Call logger.LogWarning ("message"); in your code to write to log file. If you use LogWarning be sure to set Level to Warning or more detailed (Info or Debug)
I am trying to install Ninject 3.3.2 in .NET Core, Released in May 2016. I got an error: The dependency Ninject 3.2.2 does not support framework .NETCoreApp, Version=v1.0.
Does anybody had similar problem, and is there any solution for this?
Ninject 3.3.0 was released September 26th 2017 and now targets .NET Standard 2.0 and thus also runs on .NET Core 2.0.
From the course of things (see issues/discussions on GitHub) it seems likely that some of the changes in the 4.0-beta will be reverted. I would not expected a 4.0 final shortly. Hence I would advise to go with the current version 3 release.
Just wanted to add; while both of the previous answers are correct in that ASP.Net core does provide built in dependency injection, it is NOT sufficient for more advanced scenarios. As it does not support a whole host of features that Ninject, AutoFac, Unity, or StructureMap supports.
At present, the only DI libraries that I am aware of that fully supports .net core are AutoFac and now Unity as well. It is very simple to add this in. The only thing you need to do to replace the built in DI is as follows. This example is for AutoFac but its almost identical for Unity it looks like.
First, replace the void on ConfigureServices in startup.cs with an IServiceProvider (dependency from AutoFac) like so:
public IServiceProvider ConfigureServices(IServiceCollection services)
Then create a container builder, build and resolve an IServiceProvider from ConfigureServices:
var builder = new ContainerBuilder();
builder.Populate(services);
var container = builder.Build();
return container.Resolve<IServiceProvider>();
I have a wrapper around the this second part that allows you to dynamically load and build different configurations using AutoFac modules, that I might be convinced to upload to GitHub or something if there is any interest.
Ninject does not support .NET Core. You can check it's website to be sure if there is no version that supports it.
ASP.NET Core has its own Dependency Injection container build in. See here.
Ninject does not support .Net Core, instead of this we can use dependency injection of .net core. following are the steps to implement.
Go to startup.cs at public void
ConfigureServices(IServiceCollection services)
Add services.AddTransient<Interface, Class>();
Go to the controller where you want to apply dependency injection.
Create a global private Interface _propertyName;
Pass the interface type variable to the constructor like
public Constructor(Interface name)
{
_propertyName= name;
}
Now you can access the members of the class through _propertyName.
It is possible to register dependencies manually:
services.AddTransient<IEmailService, EmailService>();
services.AddTransient<ISmsService, SmsService>();
When there are too much dependencies, it becomes difficult to register all dependencies manually.
What is the best way to implement a convention based binding in MVC 6 (beta 7)?
P.S. In previous projects I used Ninject with ninject.extensions.conventions. But I can't find a Ninject adapter for MVC 6.
No, there is no support for batch registration in the ASP.NET 5 built-in DI library. As a matter of fact, there are many features that are needed to build large SOLID applications, but are not included in the built-in DI library.
The included ASP.NET DI library is primarily meant to extend the ASP.NET system itself. For your application, you are best off using one of the mature DI libraries out there, and keep your configuration separate from the configuration that used to configure the ASP.NET system itself.
This removes the need for an adapter.
An MVC 6 adapter exists, but seeing as ASP.net 5 is still in Release candidate, it isn't yet available on NuGet so you'll need to add the ASP.NET 5 "master" branch feed from MyGet to your Visual Studio NuGet package sources.
A walkthrough to do this is available here:
http://www.martinsteel.co.uk/blog/2015/using-ninject-with-mvc6/
If it is still interesting for someone.
This is my solution of the issue with Autofac. It is required Autofac and Autofac.Extensions.DependencyInjection NuGet packages.
// At Startup:
using Autofac;
using Autofac.Extensions.DependencyInjection;
// ...
public IServiceProvider ConfigureServices(IServiceCollection services)
{
// Some middleware
services.AddMvc();
// Not-conventional "manual" bindings
services.AddSingleton<IMySpecificService, SuperService>();
var containerBuilder = new ContainerBuilder();
containerBuilder.RegisterModule(new MyConventionModule());
containerBuilder.Populate(services);
var autofacContainer = containerBuilder.Build();
return autofacContainer.Resolve<IServiceProvider>();
}
This is the convention module:
using Autofac;
using System.Reflection;
using Module = Autofac.Module;
// ...
public class MyConventionModule : Module
{
protected override void Load(ContainerBuilder builder)
{
var assemblies = new []
{
typeof(MyConventionModule).GetTypeInfo().Assembly,
typeof(ISomeAssemblyMarker).GetTypeInfo().Assembly,
typeof(ISomeOtherAssemblyMarker).GetTypeInfo().Assembly
};
builder.RegisterAssemblyTypes(assemblies)
.AsImplementedInterfaces()
.InstancePerLifetimeScope();
}
}