Разрешение экземпляров с помощью ASP.NET сердечник Ди
как вручную разрешить тип с помощью ASP.NET ядро MVC встроенная структура инъекции зависимостей?
настройка контейнера достаточно проста:
public void ConfigureServices(IServiceCollection services)
{
// ...
services.AddTransient<ISomeService, SomeConcreteService>();
}
но как я могу решить ISomeService
не выполняя инъекции? Например, я хочу сделать это:
ISomeService service = services.Resolve<ISomeService>();
нет таких методов в IServiceCollection
.
4 ответа:
The
IServiceCollection
интерфейс используется для здание контейнера внедрения зависимостей. После того, как он будет полностью построен, он будет составлен вIServiceProvider
экземпляр, который можно использовать для решения услуг. Вы можете ввестиIServiceProvider
в любом классе. ЭлементIApplicationBuilder
иHttpContext
классы могут предоставить поставщика услуг, а также, черезApplicationServices
илиRequestServices
свойства соответственно.
IServiceProvider
определяет aGetService(Type type)
метод разрешения службы:var service = (IFooService)serviceProvider.GetService(typeof(IFooService));
там также доступны несколько методов расширения удобства, таких как
serviceProvider.GetService<IFooService>()
. (Добавьте использование дляMicrosoft.Extensions.DependencyInjection
).разрешение служб внутри класса запуска
внедрение зависимостей
среда выполнения может вводить службы в конструктор
Startup
класс, напримерIHostingEnvironment
,IConfiguration
иIServiceProvider
. Обратите внимание, что этот поставщик услуг является экземпляром, построенным на уровне хостинга, и содержит только службы для запуска приложение.услуги также могут быть введены в
Configure()
метод. Вы можете добавить произвольное количество параметров после
ручное разрешение экземпляров включает в себя использование
IServiceProvider
интерфейс:разрешение зависимости при запуске.ConfigureServices
public void ConfigureServices(IServiceCollection services) { services.AddTransient<IMyService, MyService>(); var serviceProvider = services.BuildServiceProvider(); var service = serviceProvider.GetService<IMyService>(); }
разрешение зависимостей при запуске.Настроить
public void Configure( IApplicationBuilder application, IServiceProvider serviceProvider) { // By type. var service1 = (MyService)serviceProvider.GetService(typeof(MyService)); // Using extension method. var service2 = serviceProvider.GetService<MyService>(); // ... }
С Помощью Runtime Injected Services
некоторые типы могут быть введены в качестве параметров метода:
public class Startup { public Startup( IHostingEnvironment hostingEnvironment, ILoggerFactory loggerFactory) { } public void ConfigureServices( IServiceCollection services) { } public void Configure( IApplicationBuilder application, IHostingEnvironment hostingEnvironment, IServiceProvider serviceProvider, ILoggerFactory loggerfactory, IApplicationLifetime applicationLifetime) { } }
разрешение зависимостей в действиях контроллера
[HttpGet("/some-action")] public string SomeAction([FromServices] IMyService myService) => "Hello";
если вы создадите приложение с шаблоном, у вас будет что-то вроде этого на
Startup
класс:public void ConfigureServices(IServiceCollection services) { // Add framework services. services.AddApplicationInsightsTelemetry(Configuration); services.AddMvc(); }
затем вы можете добавить туда зависимостями, например:
services.AddTransient<ITestService, TestService>();
если вы хотите получить доступ к
ITestService
на вашем контроллере вы можете добавитьIServiceProvider
на конструктор и он будет введен:public HomeController(IServiceProvider serviceProvider)
затем вы можете решить службу, которую вы добавили:
var service = serviceProvider.GetService<ITestService>();
обратите внимание, что для использования общей версии вы должны включите пространство имен с расширениями:
using Microsoft.Extensions.DependencyInjection;
ITestService.cs
public interface ITestService { int GenerateRandom(); }
TestService.cs
public class TestService : ITestService { public int GenerateRandom() { return 4; } }
Автозагрузка.cs (ConfigureServices)
public void ConfigureServices(IServiceCollection services) { services.AddApplicationInsightsTelemetry(Configuration); services.AddMvc(); services.AddTransient<ITestService, TestService>(); }
HomeController.cs
using Microsoft.Extensions.DependencyInjection; namespace Core.Controllers { public class HomeController : Controller { public HomeController(IServiceProvider serviceProvider) { var service = serviceProvider.GetService<ITestService>(); int rnd = service.GenerateRandom(); }
public void ConfigureServices(IServiceCollection services) { services.AddMvc(); services.AddDbContext<ConfigurationRepository>(options => options.UseSqlServer(Configuration.GetConnectionString("SqlConnectionString"))); services.AddScoped<IConfigurationBL, ConfigurationBL>(); services.AddScoped<IConfigurationRepository, ConfigurationRepository>(); }