DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports Events Over 2 million developers have joined DZone. Join Today! Thanks for visiting DZone today,
Edit Profile Manage Email Subscriptions Moderation Admin Console How to Post to DZone Article Submission Guidelines
View Profile
Sign Out
Refcards
Trend Reports
Events
Zones
Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Partner Zones AWS Cloud
by AWS Developer Relations
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Partner Zones
AWS Cloud
by AWS Developer Relations
  1. DZone
  2. Coding
  3. Frameworks
  4. Dependency Injection in .NET Core Console Applications

Dependency Injection in .NET Core Console Applications

We take a look at how to implement dependency injection in smaller .NET Core apps, while also addressing the challenges of doing this in larger, real-world applications.

Gunnar Peipman user avatar by
Gunnar Peipman
·
Feb. 15, 19 · Tutorial
Like (5)
Save
Tweet
Share
80.19K Views

Join the DZone community and get the full member experience.

Join For Free

ASP.NET Core uses a built-in dependency injection mechanism provided by Microsoft. This blog post introduces how to use the same mechanism in .NET Core console applications. For those who like other DI/IoC frameworks, this article provides a demo about how to use Autofac with .NET Core framework-level dependency injection.

Framework-Level Dependency Injection in ASP.NET Core

I don't describe here details of dependency injection in ASP.NET Core. Those who want to find out more about it can skim through these writings:

  • Dependency injection in ASP.NET Core
  • Using dependency injection with view components
  • Injecting services to ASP.NET Core controller actions
  • ASP.NET Core: Using view injection
  • ASP.NET Core: Using third-party DI/IoC containers

Dependency Injection in .NET Core Console Applications

We can also use the same dependency injection mechanism in .NET Core command line applications. Although we don't have anything prepared for us, it's very easy to put up something similar to web applications. Actually, I prefer to use a more lightweight approach for console applications.

Before writing any code we need a NuGet package for dependency injection components: 

Microsoft.Extensions.DependencyInjection 

At a very basic level, we can create a dependency injections service provider using the following code:

static void Main(string[] args)
{
     var collection = new ServiceCollection();
     collection.AddScoped<IDemoService, DemoService>();
     // ...
     // Add other services
     // ...
     var serviceProvider = collection.BuildServiceProvider();

     var service = serviceProvider.GetService<IDemoService>();
     service.DoSomething();

     serviceProvider.Dispose();
}

Calling Dispose() on the service provider is mandatory as, otherwise, the registered instances will not get disposed. Keep this in mind.

Preparing for Disposables and Third-Party Dependency Injection Frameworks

The solution above works but it has one problem - it doesn't consider the possible use of third-party service providers. As the ServiceProvider class is sealed and third-parties cannot extend it they must use IServiceProvider interface.

public interface IServiceProvider
{
     object GetService(Type serviceType);
}

Convenience methods like GetService<T>() are defined in the ServiceProviderServiceExtensions class.

public static class ServiceProviderServiceExtensions
{
     public static IServiceScope CreateScope(this IServiceProvider provider);
     public static object GetRequiredService(this IServiceProvider provider, Type serviceType);
     public static T GetRequiredService<T>(this IServiceProvider provider);
     public static T GetService<T>(this IServiceProvider provider);
     public static IEnumerable<T> GetServices<T>(this IServiceProvider provider);
     public static IEnumerable<object> GetServices(this IServiceProvider provider, Type serviceType);
}

IServiceProvider doesn't use IDisposable and therefore it doesn't have the Dispose() method. Still, the classes that extend this interface may also extend IDisposable but we don't know it. To consider this possibility, we have to implement the disposing of the service provider in a little different way.


static void Main(string[] args)
{
     var collection = new ServiceCollection();
     collection.AddScoped<IDemoService, DemoService>();
     // ...
     // Add other services
     // ...
     IServiceProvider serviceProvider = collection.BuildServiceProvider();

     var service = serviceProvider.GetService<IDemoService>();
     service.DoSomething();

     if (serviceProvider is IDisposable)
     {
         ((IDisposable)serviceProvider).Dispose();
     }
}

Getting Code Cleaner

The Main() method is currently messed up with all the details of dependency injection. In real projects, we would probably have as many services in service the collection and filling this collection is worth a separate method. Also, I don’t like to have the service provider disposing the logic in the Main()method.

class Program
{
     private static IServiceProvider _serviceProvider;

     static void Main(string[] args)
     {
         RegisterServices();

         var service = _serviceProvider.GetService<IDemoService>();
         service.DoSomething();

         DisposeServices();
     }

     private static void RegisterServices()
     {
         var collection = new ServiceCollection();
         collection.AddScoped<IDemoService, DemoService>();
         // ...
         // Add other services
         // ...
         _serviceProvider = collection.BuildServiceProvider();
     }

     private static void DisposeServices()
     {
         if(_serviceProvider == null)
         {
             return;
         }
         if (_serviceProvider is IDisposable)
         {
             ((IDisposable)_serviceProvider).Dispose();
         }
     }
}

Things are better now as the Main() method is cleaner.

Using Autofac

I once wrote about how to use Structuremap and Autofac with ASP.NET Core. Using Autofac is simple and we need only small changes in our code to make it work.

The first thing is to add Autofac NuGet packages to the .NET Core console application project.

  • Autofac
  • Autofac.Extensions.DependencyInjection

With the Autofac packages in place, we can change the RegisterServices method to use Autofac.

private static void RegisterServices()
{
     var collection = new ServiceCollection();
     var builder = new ContainerBuilder();

     builder.RegisterType<DemoService>().As<IDemoService>();
     //
     // Add other services ...
     //
     builder.Populate(collection);

     var appContainer = builder.Build();

     _serviceProvider = new AutofacServiceProvider(appContainer);
}

We don’t need modifications to any other part of code. With these changes done and compiled our application uses Autofac now.

Wrapping Up

The dependency injection mechanism provided by Microsoft with .NET Core is popular in ASP.NET, but it can be used also in other types of .NET Core projects. It's actually very easy to get dependency injection to work as we need with small amounts of code. In real applications, the biggest part of the related code is about registering types. We were also able to use Autofac as a third-party dependency injection framework. It was easy and we made only minor changes to our existing code.

Dependency injection application .NET Console (video game CLI) Service provider ASP.NET Core ASP.NET Web Service

Published at DZone with permission of Gunnar Peipman, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

Popular on DZone

  • 5 Software Developer Competencies: How To Recognize a Good Programmer
  • Java REST API Frameworks
  • Java Code Review Solution
  • A Beginner's Guide to Infrastructure as Code

Comments

Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 600 Park Offices Drive
  • Suite 300
  • Durham, NC 27709
  • support@dzone.com
  • +1 (919) 678-0300

Let's be friends: