Accessing Dependent Injected Services in MVC 6

I am using mvc6 with vs2015 rc. After reading Using IConfiguration globally in mvc6 my code now looks like this:

startup.cs:

public void ConfigureServices(IServiceCollection services)
{
    ...
    IConfiguration configuration = new Configuration().AddJsonFile("config.json");
    services.Configure<Settings>(configuration);
}

      

my controller:

private Settings options;
public MyController(IOptions<Settings> config)
{
    options = config.Options;
}

      

this works great for controllers.

But how can I access the Settings object from somewhere else in the code, for example from within my Formatters (an implementation of IInputFormatter and hence with fixed signatures) or any other random class?

+3


source to share


1 answer


In general, when you have access to HttpContext

, you can use the property RequestServices

to access services in DI. For example, to access a service ILogger

from ObjectResult

.

public override async Task ExecuteResultAsync(ActionContext context)
{
    var logger = context.HttpContext.RequestServices.GetRequiredService<ILogger<ObjectResult>>();

      

The above usage is a little different from what you mentioned in the controller example above, because the controllers in MVC type activated

... that are responsible for building the controller are controlled through DI, which will look at the constructor parameters and populate them from registered services in DI. .. it is also called constructor injection

...

To see how DI type activation works in general (DI is independent of MVC and can even be used in a console application) see the following code snippet (taken from http://docs.asp.net/en/latest/security/data- protection / using-data-protection.html )



using System;
using Microsoft.AspNet.DataProtection;
using Microsoft.Framework.DependencyInjection;

public class Program
{
    public static void Main(string[] args)
    {
        // add data protection services
        var serviceCollection = new ServiceCollection();
        serviceCollection.AddDataProtection();
        var services = serviceCollection.BuildServiceProvider();

        // create an instance of MyClass using the service provider
        var instance = ActivatorUtilities.CreateInstance<MyClass>(services);
        instance.RunSample();
    }

    public class MyClass
    {
        IDataProtector _protector;

        // the 'provider' parameter is provided by DI
        public MyClass(IDataProtectionProvider provider)
        {
            _protector = provider.CreateProtector("Contoso.MyClass.v1");
        }

        public void RunSample()
        {
            Console.Write("Enter input: ");
            string input = Console.ReadLine();

            // protect the payload
            string protectedPayload = _protector.Protect(input);
            Console.WriteLine($"Protect returned: {protectedPayload}");

            // unprotect the payload
            string unprotectedPayload = _protector.Unprotect(protectedPayload);
            Console.WriteLine($"Unprotect returned: {unprotectedPayload}");
        }
    }
}

      

In the above example, the type MyClass

was activated by the type.

And as for your specific example about InputFormatter

, they are not type activated and hence you cannot use constructor injection with it, but you will have access to HttpContext

, and you can do as mentioned earlier in this post.

Also take a look at this article: http://blogs.msdn.com/b/webdev/archive/2014/06/17/dependency-injection-in-asp-net-vnext.aspx

+3


source







All Articles