.NET Core : Logging with Log4NET in .NET Core application

There are tons of newly created logging engines for .NET Core. Log4Net is stable, old school technology in the market. Consider using newer logging technologies, such as NLog or Serilog. But if you want to use this engine, you can make it work.

Start with the Microsoft’s tutorial, “Logging in .NET Core”. https://docs.microsoft.com/en-us/aspnet/core/fundamentals/logging/?view=aspnetcore-5.0

Install log4Net NuGet Package, and Microsoft.Extensions.Logging.Log4Net.AspNetCore package.

Install-Package log4Net
Install-Package Microsoft.Extensions.Logging.Log4Net.AspNetCore

Make changes in your Program.cs file. In the CreateHostBuilder method, configure logging with the following code:

                .ConfigureLogging((hostingContext, logging) =>
                {
                    logging.AddConsole();
                    logging.AddLog4Net();
                })

If the “AddLog4Net” method call is unrecognized by IntelliSense, make sure you have installed the Logging extension NuGet package mentioned above.

Add a new file to your project, and name it log4Net.config. The template should be used is Web Configuration file.

Make changes in the newly generated file, here you can configure the applications logging. I’ve skipped Console logging, Microsoft’s console logger visualize logs much greater. You can learn configuring Log4Net more at https://logging.apache.org/log4net/release/manual/configuration.html
A quick start configuration example:

<?xml version="1.0" encoding="utf-8"?>
<log4net>
	<root>
		<level value="ALL" />
		<appender-ref ref="file" />
	</root>
	<appender name="file" type="log4net.Appender.RollingFileAppender">
		<file value="myapp.log" />
		<appendToFile value="true" />
		<rollingStyle value="Size" />
		<maxSizeRollBackups value="5" />
		<maximumFileSize value="10MB" />
		<staticLogFileName value="true" />
		<layout type="log4net.Layout.PatternLayout">
			<conversionPattern value="%date [%thread] %level %logger - %message%newline" />
		</layout>
	</appender>
</log4net>

Windows : Allow your programs through Windows Firewall

Search for applications with “firewall” keyword.
On Windows 10 – You will need Windows Defender Firewall with Advanced Security.

Click on “Inbound rules”, and on the right pane, select “New Rule..”.

Select The Port Option

If you want a specific port to unlock, select the port option. Select the correct transport protocol and port number on the next step

You can name your rule. It is recommended to choose a name, that describes the application which uses this port.

Your port now accessible on your local network. If you want to unlock a port to the Internet, you need to set up a port forward in your router’s settings.

.NET Core : Run Core apps as Windows service.

You may want to host your .NET Core application in a Windows computer, even a Windows server. You want to get rid of Console windows, and do not want to start the app manually after the computer is started, or restart it when the application has crashed. This tutorial helps you to make a windows service from your .NET Core application, especially a .NET Core WebAPI.

Install the “Microsoft.Extensions.Hosting.WindowsServices” NuGet package for you .NET Core application. This can be achieved from NuGet package manager console:

Install-Package Microsoft.Extensions.Hosting.WindowsServices

Make changes in your Program.cs file. Add the UseWindowsService call to the CreateHostBuilder function. The result may look something like this:

        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder.UseUrls("https://0.0.0.0:8080/", "http://0.0.0.0:8081/");
                    webBuilder.UseStartup<Startup>();
                })
                .ConfigureLogging((hostingContext, logging) =>
                {
                    logging.ClearProviders();
                    logging.AddConsole();
                })
                .UseWindowsService();

This is all of the code change you need to do.
Let’s Publish your application.

Publish your application to a folder

Make the following changes in the following dialog by pressing an edit button next to a summary label.

Set the deployment mode toself-contained

Click on Publish. Once the publish is done, copy the published files to a specific directory of the computer, or an another computer. Run the powershell script above, to create a new windows service on the hosting computer.

# New-Service documentation: https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.management/new-service?view=powershell-7.1
# Script by banditoth

$serviceName = "typeyourservicename";
$serviceDescription = "typeyourdescription";
$displayName = "displayname";
$exeFilePath = "pathtoyourexefile.exe";
$serviceUserName = "MustBeDomain\User";

New-Service -Name $serviceName -DisplayName $displayName -BinaryPathName $exeFilePath -Credential $serviceUserName -Description $serviceDescription -StartupType Automatic

Do NOT forget to set the inbound policies for your application in Advanced Windows Firewall. Also keep in mind, if you want to access your web application outside of your local network, you need to forward ports on your router.

Xamarin.Forms: Bindable Property snippet for Visual Studio

Use bprop tab tab to generate commands in ViewModels with this snippet

The result of the snippet

Save the snippet file as {name}.snippet in Visual Studio’s folder: C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\VC#\Snippets\1033\Visual C#

<?xml version="1.0" encoding="utf-8" ?>
<CodeSnippets  xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
	<CodeSnippet Format="1.0.0">
		<Header>
			<Title>Bindable Property</Title>
			<Shortcut>bprop</Shortcut>
			<Description>Xamarin BindableProperty declaration code snippet</Description>
			<Author>banditoth.hu</Author>
			<SnippetTypes>
				<SnippetType>Expansion</SnippetType>
			</SnippetTypes>
		</Header>
		<Snippet>
			<Declarations>
				<Literal>
					<ID>PropertyName</ID>
					<ToolTip>The property's name</ToolTip>
					<Default>Foo</Default>
				</Literal>
				<Literal>
					<ID>Type</ID>
					<ToolTip>The type of the property</ToolTip>
					<Default>object</Default>
				</Literal>
				<Literal>
					<ID>DefaultValue</ID>
					<ToolTip>The default value of the property</ToolTip>
					<Default>null</Default>
				</Literal>
				<Literal>
					<ID>BindingMode</ID>
					<ToolTip>The binding mode of the property</ToolTip>
					<Default>TwoWay</Default>
				</Literal>
				<Literal>
					<ID>PropertyChangedHandler</ID>
					<ToolTip>The property changed handler method</ToolTip>
					<Default>null</Default>
				</Literal>
				<Literal>
					<ID>PropertyChangingHandler</ID>
					<ToolTip>The property changing handler method</ToolTip>
					<Default>null</Default>
				</Literal>
			</Declarations>
			<Code Language="csharp">
				<![CDATA[
        public static readonly BindableProperty $PropertyName$Property = BindableProperty.Create(
                                        propertyName: nameof($PropertyName$),
                                        returnType: typeof($Type$),
                                        declaringType: typeof(View),
                                        defaultValue: $DefaultValue$,
                                        defaultBindingMode: BindingMode.$BindingMode$,
                                        propertyChanged: $PropertyChangedHandler$,
					propertyChanging: $PropertyChangingHandler$);

        public $Type$ $PropertyName$
        {
            get { return ($Type$)GetValue($PropertyName$Property); }
            set { SetValue($PropertyName$Property, value); }
        }
		$end$]]>
			</Code>
		</Snippet>
	</CodeSnippet>
</CodeSnippets>

Xamarin.Forms: Lazy loaded Command snippet for Visual Studio

Use xamcomm tab tab to generate commands in ViewModels with this snippet

IntelliSense recommendation

Snippet in work

Save the snippet file as {name}.snippet in Visual Studio’s folder: C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\VC#\Snippets\1033\Visual C#

<?xml version="1.0" encoding="utf-8" ?>
<CodeSnippets  xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
	<CodeSnippet Format="1.0.0">
		<Header>
			<Title>Xamarin Lazy Command</Title>
			<Shortcut>xamcomm</Shortcut>
			<Description>Xamarin Command declaration code snippet for MVVM design pattern</Description>
			<Author>banditoth.hu</Author>
			<SnippetTypes>
				<SnippetType>Expansion</SnippetType>
			</SnippetTypes>
		</Header>
		<Snippet>
			<Declarations>
				<Literal>
					<ID>BackFieldName</ID>
					<ToolTip>Backfield Name</ToolTip>
					<Default>_backfieldname</Default>
				</Literal>
				<Literal>
					<ID>CommandName</ID>
					<ToolTip>Command name</ToolTip>
					<Default>CommandName</Default>
				</Literal>
				<Literal>
					<ID>ActionToExecute</ID>
					<ToolTip>Action to execute</ToolTip>
					<Default>() => { return; /*TODO: Implement logic for this Command*/ }</Default>
				</Literal>
        <Literal>
          <ID>ActionCanExecute</ID>
          <ToolTip>Action to determine can execute</ToolTip>
          <Default>() => true</Default>
        </Literal>
			</Declarations>
			<Code Language="csharp">
			<![CDATA[
	private Command $BackFieldName$Command;

	public Command $CommandName$Command
	{
		get { return $BackFieldName$Command ?? ($BackFieldName$Command = new Command($ActionToExecute$,$ActionCanExecute$)); }
	}
	$end$]]>
			</Code>
		</Snippet>
	</CodeSnippet>
</CodeSnippets>