2015-05-07 5 views
3

Я использую mvc6 с vs2015 rc. После прочтения Using IConfiguration globally in mvc6, мой код теперь выглядит следующим образом:Доступ к зависимым инъекционным службам в MVC 6

startup.cs:

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

мой контроллер:

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

это прекрасно работает для контроллеров.

Но как я могу получить доступ к объекту «Настройки» из другого места в коде, например, изнутри моего Formatters (реализация IInputFormatter и, следовательно, с фиксированными сигнатурами) или любого другого случайного класса?

ответ

3

В общем, если у вас есть доступ к HttpContext, вы можете использовать свойство под названием RequestServices, чтобы получить доступ к услугам в DI. Например, чтобы получить доступ к услуге ILogger с ObjectResult.

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

выше использование немного отличается от того, что вы упоминали в примере контроллера выше, так как контроллеры в MVC являются type activated ... то есть ответственность построения контроллера осуществляется через DI, который будет смотреть на параметры конструктора и заполнить их из зарегистрированных услуг в DI ... это также называется constructor injection ...

Чтобы узнать, как работает активация типа DI (в общем случае, DI не зависит от MVC и может использоваться даже в консольном приложении) , см. следующий фрагмент кода (взято из 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}"); 
     } 
    } 
} 

В приведенном выше примере тип MyClass был активирован.

А что касается вашего конкретного примера о InputFormatter, они не типа активируются и, следовательно, вы не можете использовать инъекции конструктора с ним, но вы бы иметь доступ к HttpContext и поэтому вы можете сделать, как уже упоминалось ранее в этой должности.

Также ознакомьтесь с этой статьей: http://blogs.msdn.com/b/webdev/archive/2014/06/17/dependency-injection-in-asp-net-vnext.aspx

Смежные вопросы