Reputation: 83
I'm 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 my Settings object from somewhere else in the code, like for example from inside my Formatters (implementing IInputFormatter and thus, with fixed signatures) or any other random class?
Upvotes: 3
Views: 1955
Reputation: 57949
In general where ever you have access to HttpContext
, you can use the property called RequestServices
to get access to the services in DI. For example, to get access to the ILogger
service from within ObjectResult
.
public override async Task ExecuteResultAsync(ActionContext context)
{
var logger = context.HttpContext.RequestServices.GetRequiredService<ILogger<ObjectResult>>();
The above usage is a bit different than what you mentioned in the controller example above because controllers in MVC are type activated
...that is the responsibility of constructing the controller is managed through DI which will look at the parameters of the constructor and populate them from registered services in DI...this is also called constructor injection
...
To see how DI type activation works in general (DI is independent of MVC and can used even in a console app), take a look at the following snippet of code (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 type activated.
And regarding your specific example about InputFormatter
, they are not type activated and hence you cannot use constructor injection with it, but you would have access to the HttpContext
and so 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
Upvotes: 3