Dependencyinjection: Question: How do you use DependencyInjection in a Console App?

Created on 4 Feb 2016  Â·  10Comments  Â·  Source: aspnet/DependencyInjection

I want to build a WebJob that has access to my infrastructure but there are no examples online anywhere about how to register services nor how to use them in a Console App.

question

Most helpful comment

An sketch of what someone would expect coming from a WebApp:

    public class Program
    {
        public IConfigurationRoot Configuration { get; set; }
        public IServiceProvider ServiceProvider;

        public Program(IApplicationEnvironment env, IRuntimeEnvironment runtime)
        {
            // What can I do with env and runtime?
            var services = new ServiceCollection();
            ServiceProvider = services.BuildServiceProvider();

            var builder = new ConfigurationBuilder()
                .AddJsonFile("appsettings.json")
                .AddEnvironmentVariables();

            Configuration = builder.Build();
        }

        private void ConfigureServices(IServiceCollection services)
        {
            // Who calls this?
            services.AddEntityFramework()
                .AddSqlServer()
                .AddDbContext<DbContext>(options =>
                    options.UseSqlServer(Configuration["Data:DefaultConnection:ConnectionString"]));
            services.AddScoped<IMyService, MyService>();
        }

        public void Run(IMyService service, DbContext dbContext)
        {
            // My program code.
        }

        public static void Main(string[] args)
        {
            // Entry point. What in here?
        }
    }

Any idea? Please be specific.

All 10 comments

Maybe this post can help:
ASP.NET 5 - A Deep Dive into the ASP.NET 5 Runtime
https://msdn.microsoft.com/en-us/magazine/dn913182.aspx

It is still not clear how can I get my services registered in a
configureservices method and injected in my program constructor.
On Feb 4, 2016 10:21 AM, "chr1sk0n" [email protected] wrote:

Maybe this post can help:
ASP.NET 5 - A Deep Dive into the ASP.NET 5 Runtime
https://msdn.microsoft.com/en-us/magazine/dn913182.aspx

—
Reply to this email directly or view it on GitHub
https://github.com/aspnet/DependencyInjection/issues/357#issuecomment-179727288
.

An sketch of what someone would expect coming from a WebApp:

    public class Program
    {
        public IConfigurationRoot Configuration { get; set; }
        public IServiceProvider ServiceProvider;

        public Program(IApplicationEnvironment env, IRuntimeEnvironment runtime)
        {
            // What can I do with env and runtime?
            var services = new ServiceCollection();
            ServiceProvider = services.BuildServiceProvider();

            var builder = new ConfigurationBuilder()
                .AddJsonFile("appsettings.json")
                .AddEnvironmentVariables();

            Configuration = builder.Build();
        }

        private void ConfigureServices(IServiceCollection services)
        {
            // Who calls this?
            services.AddEntityFramework()
                .AddSqlServer()
                .AddDbContext<DbContext>(options =>
                    options.UseSqlServer(Configuration["Data:DefaultConnection:ConnectionString"]));
            services.AddScoped<IMyService, MyService>();
        }

        public void Run(IMyService service, DbContext dbContext)
        {
            // My program code.
        }

        public static void Main(string[] args)
        {
            // Entry point. What in here?
        }
    }

Any idea? Please be specific.

It is still not clear how can I get my services registered in a
configureservices method and injected in my program constructor.

There's no such things as a ConfigureServices or injecting anything in Program's constructor for a console application (or a web app for that matter, it's all been removed).

Something like this should work:

public static class Program
{
    public static void Main()
    {
        var services = new ServiceCollection();

        // TODO: Add your services to the collection. Here you could call your own ConfigureServices method

        var provider = services.BuildServiceProvider();

        // TODO: Get the services you need from the provider.
    }
}

If you're running with DNX and you need access to the platform services, you can add the Microsoft.Extensions.PlatformAbstractions package and use PlatformServices. Default to get a hold of IApplicationEnvironment and IRuntimeEnvironment.

I tried but I get this exception:

No service for type 'IMyService' has been registered.

This is the code:

            var services = new ServiceCollection();
            // Set up configuration sources.
            var builder = new ConfigurationBuilder()
                .AddJsonFile("appsettings.json")
                .AddEnvironmentVariables();
            Configuration = builder.Build();
            ConfigureServices(services);
            var provider = services.BuildServiceProvider();
            IMyService service = provider.GetRequiredService<IMyService>();

If I change GetRequiredService for GetService I get:

Unable to resolve service for type 'Microsoft.AspNet.Http.IHttpContextAccessor' while attempting to activate 'IMyService'.

@pepevc silly question, but are you sure that your ConfigureServices method is adding the Microsoft.AspNet.Http.IHttpContextAccessor service to the container? It of course won't automatically show up there because this isn't running in ASP.NET - it's your own console app.

I came here to update the finding: that was it. I am wondering why the EntityFramework needs that service...

Thank you all.

Hint: The VS template should include some DI in the basic Console App. At least the Configuration builder.

@pepevc consider starting a discussion in https://github.com/aspnet/EntityFramework/issues/ for that.

The reason the VS template doesn't have DI or config is to closely match what the regular Console App project template in VS always had: just the most basic stuff to get a generic app running.

It would be just another project template, in the same fashion we have with WebApps (Empty, with Authentication, etc).

I just recreated a Startup class that configures the services and then launches the Program with everything I need automatically injected in the Program constructor.

A simple template like this would be nice. Otherwise inexperienced people in this particular tech get lost trying to understand all the conventions when a simple glimpse of a working piece of code solves the issue in a matter of seconds.

@pepevc you can file a suggestion in the Templates repo: https://github.com/aspnet/Templates/issues/

Was this page helpful?
0 / 5 - 0 ratings