What is Dotnet?

What is Dotnet?

**Introduction to .Net Framework:** <a href="https://onlineitguru.com/dot-net-online-training-placement.html">.*Net online training*</a> is a software framework that is designed and developed by Microsoft.Microsoft began developing the .net...

Introduction to .Net Framework:
.Net online training is a software framework that is designed and developed by Microsoft.Microsoft began developing the .net framework in the year 1990 originally under the name of next-generation windows services(NGWS). The first version of the .Net Framework was net 1.0.

Features of .net framework are
Interoperability
Language independence
Type safety
Portability
Security
Memory management
performance
.net framework used to develop 3 kinds of applications they are
1.Web applications
2. Windows applications
3. Mobile applications
To Get depth knowledge in .net online training Hyderabad
.Net framework supports 60 programming languages. In this 11 programming language designed and developed by Microsoft and remaining are supported by .Net framework but not developed by Microsoft.some of the Microsoft supported languages are

  1. C#.net
    2.Vb.net
    3.C++.net
    4.J#.net
    5.F#.net
    6.windows Power-Shell
    7.iron ruby
    8.iron python
    9.C OMEGA
    10.ASML(Abstract State Machine Language)
    Main components of the .net framework
    .Net framework supports 4 types of components they are
    1.Common Language Runtime(CLR),
    2.Framework Class Library(FCL),
    3.Core languages(WinForms,ASP.Net,ADO.Net),and
    4.Other Modules(WCF,WPF,WF,Card Space,LINQ,Entity Framework,Parallel Linq,etc.)
    CLR: CLR stands for common language runtime.
    It is the effective machine component of the .net framework.
    It is an execution engine that converts the given program into native code.
    CLR acts as an interface between the framework and the operating system.
    CLR provides various services they are type-safety and memory management, thread management, remoting, robustness, etc. Basically, CLR is responsible for controlling the .net programs of any .Net framework.
    It also helps in the controlling of code.
    The code that selects at runtime is called managed code and that does not select at runtime is called unmanaged code.
    FCL: FCL stands for the framework class library. FCL is the collection of the standard library that contains a collection of reusable class libraries and object-oriented methods that are used to develop an application.
    If we want to install the .net framework firstly we have to install the CLR and FCL into the system.
    The following diagram shows the description of the .Net Framework

Is .Net platform independent or dependent?
Basically, the platform is the mixture of operating system architecture and CPU architecture. platform-dependent means programming language that runs on the specific operating system only that does not supports other operating systems.
.Net framework can able run on windows based operating system hence .net is the platform-dependent language.
We can convert the .net framework from platform-dependent to platform-independent by using the Mono Framework.
By using this Mono Framework we can run .Net applications in any operating systems. Mono framework is one of the third-party company which is developed by Novell company. Now it is part of the microfocus company.
Release History of .net Framework and its similarity with the different windows versions
.NET VERSION
CLR VERSION
DEVELOPMENT TOOL
WINDOWS SUPPORT
1.0
1.0
Visual Studio .NET
XP SP1
1.1
1.1
Visual Studio .NET 2003
XP SP2, SP3
2.0
2.0
Visual Studio 2005
N/A
3.0
2.0
Expression Blend
Vista
3.5
2.0
Visual Studio 2008
7, 8, 8.1, 10
4.0
4
Visual Studio 2010
N/A
4.5
4
Visual Studio 2012
8
4.5.1
4
Visual Studio 2013
8.1
4.5.2
4
N/A
N/A
4.6
4
Visual Studio 2015
10 v1507
4.6.1
4
Visual Studio 2015 Update 1
10 v1511
Some of the most important points:
If we want to develop any .net applications we have to install the Microsoft visual studio. If the user wants to work on the visual studio first install the .net framework software on the system.
Some of the older versions of Windows OS like XP SP1SP2, SP3, etc. .net framework was joined with installation media.
How .net is used for?
.Net is a rich feature which used to develop different next-generation applications.
they are
business functions
Re-Designing
Interoperable applications
Gaming
Threading
Communication
Multi-tired software architecture
Cross-platform
Mobile apps
Advantages of .Net:
Object-oriented: The code that is writing in the .net framework in the form of objects only.
Cashing: The cashing of .net is very fast and easy-to-use.
Easy maintenance: The code that is written in .net framework is very simple and easily maintainable. This is Because source code and HTML code combined together
Time-saving:.Net removes a large part of coding sections. Hence we can save time while working with .net applications.
Simplicity: Performing tasks in .net framework is extremely simple and easily understandable.
Future rich:.net framework provides a range of features that are explored by developers in order to create powerful .net applications.
Consistency: The management and observing of all the processes performed by the .net framework. If one process is stopped, then it will take another process this is all about consistency feature in .net.
Monitoring:.Net provides an important advantage that is automatic monitoring. By using this automatic monitoring we can easily notice problems like infinite loops, memory leaks, etc.
Dis-advantages of .Net:
limited object-relational(OR)support: It is found to be limited at times because t supports in entity framework only.
Slower than native code: Managed code that runs in the .net framework slower than native code.
Vendor Lock-in: Vendor lock-in means future development will depend on Microsoft only.
Expensive: In some cases, applications of .net can turn into very expensive.
Reasons to learn .Net:
Here the few reasons to learn the .net for the career those are
Resources available
Large community
Visual studio
Multiple server platforms
Job opportunity
These are the few details on Dotnet.I hope you people got the basic idea on Dotnet. You can get more practical knowledge when you enrol for Dotnet Online Training

Angular 9 Tutorial: Learn to Build a CRUD Angular App Quickly

What's new in Bootstrap 5 and when Bootstrap 5 release date?

What’s new in HTML6

How to Build Progressive Web Apps (PWA) using Angular 9

What is new features in Javascript ES2020 ECMAScript 2020

PHP Vs ASP.NET: How to Choose the Right One?

PHP Vs ASP.NET: How to Choose the Right One?

Are you a business owner looking for PHP web development services or ASP.Net development services, but unable to decide the right technology for your project? Are you looking for the pros and cons of ASP.Net and PHP to take an effective...

Are you a business owner looking for PHP web development services or ASP .Net development services, but unable to decide the right technology for your project? Are you looking for the pros and cons of ASP .Net and PHP to take an effective decision?

We have no doubt about the fact that both of these technologies have become successful ventures, and have developed great websites.

But, the question still remains fresh for all of us, especially those from a non-technical background and the question is: Which platform should we choose at the time of starting with web-apps exercise?

On one side, PHP is a free and open-source platform while ASP .Net is a paid Microsoft platform. PHP is a mix between a programming language and a web framework whereas .NET is a straight application framework.

Now, Let’s have a neat and clean comparison on PHP & DotNet on different parameters.

In the below blog, I have covered the differences between the two and tried to decipher which is the better one.

Read the full blog here: PHP Vs ASP.NET: How to Choose the Right One?

Introduction to ASP.NET Core Tutorials | ASP.NET Training | Simpliv

Introduction to ASP.NET Core Tutorials | ASP.NET Training | Simpliv

This course is designed you give you a deep understanding of modern .NET concepts without confusing you or making you lost in the sea of .net technologies that keep springing up now and then. Get behind the modern .NET directions and grasp all that is going on nowadays in the world of .NET.

Description
Last years a great number of technologies came up to the world of .NET platform: nowadays we have the full (classic) .NET framework with CLR as a runtime, Mono with its own runtime, .NET Core with Core CLR, WinRT, UWP and Xamarin, a new JIT compiler RyuJit, .NET Standard, PCL, .Net Native, new Roslyncompiler with open API, NuGet based project management. God’s sake! It’s so simple to get lost in that ocean of technologies. You need to understand the overall picture to feel comfortable today. Didn’t you feel like a small fish in the ocean last time? Well, I did. I questioned myself, "what the hell is going on around me?" I didn’t quite understand the directions in which technologies develop. I didn’t know what to expect, what to learn next. In such situation, you feel helpless. And what we are going to do in the course is that we’re going to eliminate this nasty feeling of being helpless by learning all the most important notions in the modern .NET platform.

Teaching Approach

No fluff, no ranting, no beating the air. I esteem your time. The course material is succinct, yet comprehensive. All important concepts are covered. For absolute beginners, I offer my help on Skype absolutely free if requested. Don't forget that this course has English subtitles, so if you don't understand my accent, feel free to turn them on.

Take this course and you will be satisfied.

Build a deep understanding of modern .NET concepts

If you go behind the modern .NET directions, then this course is for you. This course will bring a whole picture of what's going on nowadays in the world of .NET, so you'll understand what you can and what you can't achieve using specific technologies. This course is like a navigation map.

Content and Overview

The goal of this course is to reveal the whole picture of the .NET world. One of the most profound technologies is the new .NET Core platform, so learning it, is a second primary goal of this course.

Of course, all the way along we will discuss all the other technologies I mentioned above.

This course is built for all kind of C# developers who are interested in learning the .NET platform. This course is beneficial for juniors as well as for seniors who want to stay well-informed about modern .NET platform. I’m sure any student will find something interesting and useful in this course.

The main prerequisite is to be familiar with development on the .NET platform in C#. That’s all you need.

In short, the course covers the following topics:

Classic .net platform, it’s building blocks, the history of this platform
Mono platform, it’s building blocks. You’ll figure out if classic .NET and Mono are compatible. We will compare classic .NET framework and Mono platform
.NET Core is the new cross-platform .NET platform. We will understand what’s different here comparing to other .NET platform and this platform means for the future of the .NET world platform
.NET Native is an interesting ahead-of-time compilation technology. You’ll know that a form of .NET Native comes to .NET Core as well.
Do you really understand what is UWP? How it is related to WinRT and what WinRT actually is?
Roslyn as a compiler platform
NuGet as a system of dependencies management
Installation of .NET Core
Command-Line Interface (CLI) of .NET Core
Deployment in .NET Core: SCD and FDD
The problem of cross-compiling
Portable Class Library (PCL)
.NET Standard
.NET Portability Analyzer
Unit-Testing in .NET Core
Upcoming Changes quick overview
How long is this course: The course is around 2 hours. All are video lectures. You will be able to download all the slides and code samples used in the course.

Keywords related to the course:

.NET Core
C#.NET Core
.NET Standard
NuGet
Core CLR
.NET Ecosystem
Who is the target audience?

Anyone from beginner to senior
Basic knowledge
Need to be familiar with development on the .NET platform in C#
What will you learn
Create, deploy and manage .NET Core applications
Disctinct different technologies: platforms, runtimes, compilers and so on
Create and use .NET Standard Libraries
Understand all the modern .NET concepts
Write unit-tests in .NET Core
To continue:

How to make a Windows Service from .Net Core 3.0

How to make a Windows Service from .Net Core 3.0

NET Core 3.0, it's a lot easier to create Windows Services: just a single line of code ... If the application runs on a Windows system, the method ..

In this blog post, we will create a demo Windows Service application which includes a set of features such as reading configurations, logging to files, dependency injection, file system watcher, and so on. The application will be written in .NET Core 3.0, which introduces new concepts like generic host, worker service, background service, and so on. We will go over the installation process of our Windows Service application as well.

The complete solution can be found in this GitHub repository. This application can be used as a bare-bones template for Windows Service applications or Console applications.

Why do we build Windows Service applications?

Microsoft Windows services allow us to create long-running executable applications that run in their own Windows sessions. Windows services don’t have any user interface, can be automatically started when the computer reboots, and can be paused and restarted.

Windows services are ideal for long-running functionality that does not interfere with other users who are working on the same computer. For example, in a Windows Service application, we can use a FileSystemWatcher to listen to the file system change notifications and raise events when a directory, or a file in a directory, changes. The beauty is that the Windows Service application handles all the events in background.

Practically, we usually run services in the security context of a specific user account that is different from the logged-on user or the default computer account. So a hacker cannot easily mess up the file system or the service related database through a compromised computer.

If you have created a Windows Service application in .NET framework, then you must remember the pain of debugging the Windows Service application. During those old days, the tool TopShelf helped us a little bit, but not much. Now, with the .NET Core 3.0, the experience of developing a Windows Service application is much more pleasant. In my opinion, the concept of a Windows Service is clearer as well.

In order to follow along, you need to have .NET Core 3.0 SDK installed. Also, you need to have Admin privilege in your computer or the hosting server, so that you can install the Windows Service and/or remove it.

Let’s first create a basic ASP.NET Core application and configure it to be able to be hosted in a Windows Service.

Create a bare-bones Windows Service application

We will use the worker service template from .NET Core as a starting point. If you are using Visual Studio, then you can follow the steps below:
(1) Create a new project.
(2) Select **Worker Service**. Select **Next**.
(3) Set the project name as “Demo”. Then select **Create**.
(4) In the **Create a new Worker service** dialog, select **Create**.

If you are using .NET CLI, then you can use the following command to create a solution which contains a Worker Service project.

dotnet new sln -o WindowsServiceDemo -n Demo
cd .\WindowsServiceDemo\
dotnet new worker -o Demo
dotnet sln add .\Demo\

In order to enable the worker service app to run as a Windows Service, we need to update the project a little bit by doing the following steps:

  1. Add a NuGet package [Microsoft.Extensions.Hosting.WindowsServices](https://www.nuget.org/packages/Microsoft.Extensions.Hosting.WindowsServices).
  2. Update the Program.cs by adding the IHostBuilder.UseWindowsService() extension method to the CreateHostBuilder process. The code snippet below shows an example.

Program.cs

public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .UseWindowsService()
            .ConfigureAppConfiguration((context, config) =>
            {
                // configure the app here.
            })
            .ConfigureServices((hostContext, services) =>
            {
                services.AddHostedService<Worker>();
            });
}

Add line 10 to make the worker service app to be able to host in a Windows Service

In the code above, line 10 is the key to creating a Windows Service app. When the application is hosted in a Windows Service, the extension method IHostBuilder.UseWindowsService() will set the ContentRoot, configure logging, set the host lifetime to WindowsServiceLifetime, and so on.

Voila~ Now we can build the app.

Through these simple steps, we have created an ASP.NET Core app that can be hosted in a Windows Service. Moreover, this app is automatically a Console application that we can run it directly via executing the Demo.exe file in the output folder. This setup allows us to debug the application as a Console app, and allows us to host the app in a Windows Service with minimum configurations.

Bonus: we can check if the app is running as a Windows Service or not using the bool WindowsServiceHelpers.IsWindowsService() method, which returns true if the current process is hosted as a Windows Service, otherwise false.

Add Serilog as a logging provider

Logging is essential for monitoring the status of our application. We definitely need logging for Windows Service applications, because they don’t have any interface and they are totally in the background. In this application, we will use Serilog to log messages to both Console output and physical files.

We will need to install the following NuGet packages that are related to Serilog: Serilog.Enrichers.Thread, Serilog.Extensions.Hosting, Serilog.Sinks.Console, and Serilog.Sinks.File. All of these NuGet packages should use their latest versions.

Then we update the Main method in the Program.cs file to be the code snippet below.

Program.cs

public static void Main(string[] args)
{
    const string loggerTemplate = @"{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u4}]<{ThreadId}> [{SourceContext:l}] {Message:lj}{NewLine}{Exception}";
    var baseDir = AppDomain.CurrentDomain.BaseDirectory;
    var logfile = Path.Combine(baseDir, "App_Data", "logs", "log.txt");
    Log.Logger = new LoggerConfiguration()
        .MinimumLevel.Override("Microsoft", LogEventLevel.Warning)
        .Enrich.With(new ThreadIdEnricher())
        .Enrich.FromLogContext()
        .WriteTo.Console(LogEventLevel.Information, loggerTemplate, theme: AnsiConsoleTheme.Literate)
        .WriteTo.File(logfile, LogEventLevel.Information, loggerTemplate,
            rollingInterval: RollingInterval.Day, retainedFileCountLimit: 90)
        .CreateLogger();

    try
    {
        Log.Information("====================================================================");
        Log.Information($"Application Starts. Version: {System.Reflection.Assembly.GetEntryAssembly()?.GetName().Version}");
        Log.Information($"Application Directory: {AppDomain.CurrentDomain.BaseDirectory}");
        CreateHostBuilder(args).Build().Run();
    }
    catch (Exception e)
    {
        Log.Fatal(e, "Application terminated unexpectedly");
    }
    finally
    {
        Log.Information("====================================================================\r\n");
        Log.CloseAndFlush();
    }
}

public static IHostBuilder CreateHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args)
        .UseWindowsService()
        .ConfigureAppConfiguration((context, config) =>
        {
            // Configure the app here.
        })
        .ConfigureServices((hostContext, services) =>
        {
            services.AddHostedService<Worker>();
        })
        .UseSerilog();

add Serilog

In the code snippet above, we added two logging sinks: (1) Console (line 10) with color theme, and (2) plain text files (line 11) that are rolling every day. The logging message are enriched with ThreadID and LogContext, which are two common fields that can help us diagnosing issues if any.

In the end, we add the line 44, .UseSerilog(), to the HostBuilder, so that the host will use Serilog as a logging provider.

Caveat:
By default, the log file path (in line 11) should be able to use a relative path with respect to the assembly entry file. However, when an application is hosted in a Windows Service, the current working directory is set to the “ _C:\WINDOWS\system32_” folder, which is not a good place for log files. So I used an absolute path, with respect to AppDomain.CurrentDomain.BaseDirectory, to make sure the log files are written and saved into the proper location.

Now, if we run the application, we should be able to see both Console outputs and a log file with all logging messages.

We can implement the Windows Service app to run scheduled background tasks, execute long running jobs, and so on. In this blog post, we will utilized a FileSystemWatcher to run background tasks when some specific file system events raise. This process is useful to monitor shared network folders or SFTP folders, in which users drop files.

Add FileSystemWatcher

For those who are new to FileSystemWatcher, you can read more from this article in Microsoft Docs. We are going to add a FileSystemWatcher to listen to the file system change notifications when a new txt file is created in a directory, C:\temp.

The FileSystemWatcher is better to live in the Worker service, because they will have the same lifetime. We initialize the FileSystemWatcher when the Worker service starts, and we dispose the FileSystemWatcher when the Worker service disposes.

The code snippet below shows an example Worker.cs file.

Worker.cs

public class Worker : BackgroundService
{
    private readonly ILogger<Worker> _logger;
    private FileSystemWatcher _folderWatcher;
    private readonly string _inputFolder;

    public Worker(ILogger<Worker> logger)
    {
        _logger = logger;
        _inputFolder = @"C:\temp";
    }

    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        await Task.CompletedTask;
    }

    public override Task StartAsync(CancellationToken cancellationToken)
    {
        _logger.LogInformation("Service Starting");
        if (!Directory.Exists(_inputFolder))
        {
            _logger.LogWarning($"Please make sure the InputFolder [{_inputFolder}] exists, then restart the service.");
            return Task.CompletedTask;
        }

        _logger.LogInformation($"Binding Events from Input Folder: {_inputFolder}");
        _folderWatcher = new FileSystemWatcher(_inputFolder, "*.TXT")
        {
            NotifyFilter = NotifyFilters.CreationTime | NotifyFilters.LastWrite | NotifyFilters.FileName |
                              NotifyFilters.DirectoryName
        };
        _folderWatcher.Created += Input_OnChanged;
        _folderWatcher.EnableRaisingEvents = true;

        return base.StartAsync(cancellationToken);
    }

    protected void Input_OnChanged(object source, FileSystemEventArgs e)
    {
        if (e.ChangeType == WatcherChangeTypes.Created)
        {
            _logger.LogInformation($"InBound Change Event Triggered by [{e.FullPath}]");

            // do some work

            _logger.LogInformation("Done with Inbound Change Event");
        }
    }

    public override async Task StopAsync(CancellationToken cancellationToken)
    {
        _logger.LogInformation("Stopping Service");
        _folderWatcher.EnableRaisingEvents = false;
        await base.StopAsync(cancellationToken);
    }

    public override void Dispose()
    {
        _logger.LogInformation("Disposing Service");
        _folderWatcher.Dispose();
        base.Dispose();
    }
}

A background service with a file system watcher

In line 28, we set the filter to be “*.TXT”, which tells the FileSystemWatcher to watch for specify the type of files in the input folder, which is the txt file type in this project. The FileSystemWatcher accepts event handlers for Changed, Created, Deleted, and Renamed events. For demo purposes, we only handle the new txt file Created events in this project.

If we run the application, then we are able to observe the effects of the Worker service and the FileSystemWatcher. Once a new txt file is created in the C:\temp folder, the application will get notified and the Input_OnChanged event delegate will be called.

Awesome. Now we have a background process to watch the file changes.

Note: In order to work on files or folders in the file system, it’s important to make sure that the current user (for debugging purposes) and the Log On As account have proper permission to the intended working directory.

Bonus: We can use WindowsIndentity.GetCurrent().Name to verify the current user name. I usually write the user name to the application logs as a tracking measure.

Add configuration files

You might have noticed that the input folder path is a magic string, C:\temp, in the code above. We can improve the code by loading a configuration file to get the input folder path.

We add a JSON object “AppSettings” to the appsettings.json file. For demo purposes, we only add one property, InputFolder, in the AppSettings object. The settings can be extended as needed.

appsettings.json

"AppSettings": {
    "InputFolder": "C:\\temp"
}

In order to bind the AppSettings JSON value, we create a C# class file, AppSettings.cs, as follows.

AppSettings.cs

public class AppSettings
{
    public string InputFolder { get; set; }
}

Then, we register the configuration, AppSettings, in the Dependency Injection (DI) container by adding a line in the Program.cs file as follows.

Program.cs

.ConfigureServices((hostContext, services) =>
{
    services.AddHostedService<Worker>();
    services.Configure<AppSettings>(hostContext.Configuration.GetSection("AppSettings"));
})

In the end, we can inject the settings to the Worker service like the following code snippet.

Worker.cs

public Worker(ILogger<Worker> logger, IOptions<AppSettings> settings)
{
    _logger = logger;
    _inputFolder = settings.Value.InputFolder;
}

In this way, we eliminated the magic string, and we have a more extendable code base.

Caveat: The Hosting Environment
It is known that ASP.NET Core web app uses the environment variable ASPNETCORE_ENVIRONMENT to determine the web host environment. However, in the case of Generic Host (link), the host environment is determined by the environment variable DOTNET_ENVIRONMEN by default, which is different from the one for Web applications. Well, you can always overwrite the HostEnvironment using a key-value pair with the key “environment” and its value.

We don’t need to explicitly add JSON file providers for the appsettings.json and appsettings.{environment}.json files, because they are automatically configured inside the Host.CreateDefaultBuilder(args) method. So you might want to make sure the environment name is correctly set, if you want to load correct settings in the appsettings.{environment}.json file.

Add a Scoped Service

In many cases, our applications depend on some short-lived services, for example, database connections, HTTP Client. We don’t want the application holds unnecessary stale resources, so we register those short-lived services as Scoped or Transient dependencies in the DI container. All these should be straightforward in Web applications. However, in Windows Service Applications, there’s some extra work to do.

For demo purposes, we will keep this application simple, and we add two contrived services in the Demo project. The following two code snippets show the SeriveA and ServiceB classes.

ServiceA.cs

public interface IServiceA
{
    void Run();
}

public class ServiceA : IServiceA
{
    private readonly ILogger<ServiceA> _logger;
    private readonly IServiceB _serviceB;

    public ServiceA(ILogger<ServiceA> logger, IServiceB serviceB)
    {
        _logger = logger;
        _serviceB = serviceB;
    }

    public void Run()
    {
        _logger.LogInformation("In Service A");
        _serviceB.Run();
    }
}

ServiceB.cs

public interface IServiceB
{
    void Run();
}

public class ServiceB : IServiceB
{
    private readonly ILogger<ServiceB> _logger;

    public ServiceB(ILogger<ServiceB> logger)
    {
        _logger = logger;
    }

    public void Run()
    {
        _logger.LogInformation("In Service B");
    }
}

We inject the ServiceB into the ServiceA, and we will use ServiceA as an entry point to run the process when a new file is created and detected by the FileSystemWatcher in the Worker service.

We register the ServiceA and the ServiceB in the Program.cs file as follows.
Program.cs

.ConfigureServices((hostContext, services) =>
{
    services.AddHostedService<Worker>();
    services.Configure<AppSettings>(hostContext.Configuration.GetSection("AppSettings"));
    services.AddScoped<IServiceA, ServiceA>();
    services.AddScoped<IServiceB, ServiceB>();
})

Then we inject the IServiceA to the Worker service and call serviceA.Run() as follows.

Worker.cs

public class Worker : BackgroundService
{
    // ...
    private readonly IServiceA _serviceA;

    public Worker(ILogger<Worker> logger, IOptions<AppSettings> settings, IServiceA serviceA)
    {
        // ...
        _serviceA = serviceA;
    }
    // ...
    protected void Input_OnChanged(object source, FileSystemEventArgs e)
    {
        if (e.ChangeType == WatcherChangeTypes.Created)
        {
            // ...
            _serviceA.Run();
            // ...
        }
    }
    //...
}

All done. Everything is hooked up. However, when we run the program, we will get an error immediately. The error message is similar to the following.

System.AggregateException: Some services are not able to be constructed (Error while validating the service descriptor 'ServiceType: Microsoft.Extensions.Hosting.IHostedService Lifetime: Singleton ImplementationType: Demo.Worker': Cannot consume scoped service 'Demo.Services.IServiceA' from singleton 'Microsoft.Extensions.Hosting.IHostedService'.)

The key part of the error message is “cannot consume scoped service from singleton”. This error is due to the Worker service has a singleton lifetime, while the ServiceA has a scoped lifetime, which would be garbage collected before the Worker service. Thus they cause a violation in DI container.

In order to make it work, we can borrow the IServiceProvider to create a scope and resolve the scoped service. The following code snippet shows an example.

Worker.cs

public class Worker : BackgroundService
{
    // ...
    private readonly IServiceProvider _services;

    public Worker(ILogger<Worker> logger, IOptions<AppSettings> settings, IServiceProvider services)
    {
        // ...
        _services = services;
    }
    // ...
    protected void Input_OnChanged(object source, FileSystemEventArgs e)
    {
        if (e.ChangeType == WatcherChangeTypes.Created)
        {
            // ...
            using (var scope = _services.CreateScope())
            {
                var serviceA = scope.ServiceProvider.GetRequiredService<IServiceA>();
                serviceA.Run();
            }
            // ...
        }
    }
    //...
}

In this way, the DI container is able to resolve all dependencies. Problem solved!

Now, we are ready to deploy our application to a Windows Service.

Windows Service management

To achieve best performance, we first need to build our application in the Release mode.

If you have PowerShell 6.2+, then you can use a series of commands to install, start/stop, remove Windows Services. These commands include New-Service, Start-Service, Get-Service, Stop-Service, and Remove-Service.

BTW: Make sure you have Admin privilege to do these operations.

Here, we will take the old fashion approach to manage Windows Services using sc.exe in CMD. Note: in CMD environment only. The sc commands might not work in PowerShell environment.

The commands to create, start/stop, and delete a Windows Service are shown in the following code snippet.

cmd.bat

:: Create a Windows Service
sc create DemoService DisplayName="Demo Service" binPath="C:\full\path\to\Demo.exe"

:: Start a Windows Service
sc start DemoService

:: Stop a Windows Service
sc stop DemoService

:: Delete a Windows Service
sc delete DemoService

It is worth mentioning that the binPath needs to be the full path of the exe file of the application. All the commands should be easy to use.

Looks like we have covered all the stuff as planed. Hope you have learned something new, and I bet you are able to get started to create a Windows Service app in .NET Core 3 now.

If you need reference, you can find the full project in this GitHub repository.

Thanks for reading.