ASP.NET Core DependencyResolver

在ASP.NET MVC中,可以通过DependencyResolver.Current.GetService()获得一些依赖。 ASP.NET Core中有类似的东西吗?

就在这里。 在ASP.NET Core 1.0.0中,来自HttpContext的请求中可用的服务通过RequestServices集合[1]公开:

 this.HttpContext.RequestServices 

您可以使用GetService方法通过指定依赖项的类型来检索依赖项:

 this.HttpContext.RequestServices.GetService(typeof(ISomeService)); 

通常,您不应该直接使用这些属性,而是更喜欢通过类的构造函数请求类所需的类,并让框架注入这些依赖项。 这会产生更容易测试并且更松散耦合的类。

[1] https://docs.asp.net/en/latest/fundamentals/dependency-injection.html#request-services

如果你真的需要它,你可以自己写一个。 首先 – 创建AppDependencyResolver类。

 public class AppDependencyResolver { private static AppDependencyResolver _resolver; public static AppDependencyResolver Current { get { if (_resolver == null) throw new Exception("AppDependencyResolver not initialized. You should initialize it in Startup class"); return _resolver; } } public static void Init(IServiceProvider services) { _resolver = new AppDependencyResolver(services); } private readonly IServiceProvider _serviceProvider; public object GetService(Type serviceType) { return _serviceProvider.GetService(serviceType); } public T GetService() { return _serviceProvider.GetService(); } private AppDependencyResolver(IServiceProvider serviceProvider) { _serviceProvider = serviceProvider; } } 

请注意_serviceProvider.GetService(); 仅当您using Microsoft.Extensions.DependencyInjection;添加时才可用using Microsoft.Extensions.DependencyInjection; 。 如果向project.json添加"Microsoft.Extensions.DependencyInjection": "1.0.0" ,那么该命名空间将可用。 比你应该在你的startup类中调用Init方法。 例如

  public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) { AppDependencyResolver.Init(app.ApplicationServices); //all other code 

之后,您可以在任何地方使用它,与DependencyResolver.Current相同。 但我的建议 – 只有在没有其他选择的情况下才使用它。

服务在Asp.net核心,它在HttpContext

 this.HttpContext.RequestServices 

通过使用此服务,可以获得服务。 并且您还可以使用GetService方法通过指定依赖项的类型来检索依赖项:

 this.HttpContext.RequestServices.GetService(typeof(ISomeService)); 

IServiceProvider有扩展方法:GetService,GetRequiredService和GetServices。 它们都具有通用和非通用版本。 在Asp.Net Core Web项目中,您可以通过DI或IApplicationBuilder获取对IServiceProvider的引用。 在Console应用程序中,您应该创建自己的IServiceProvider实例并在某处存储引用

 var services = new ServiceCollection(); ... ServiceProvider = services.BuildServiceProvider(); 

我认为这可能是一个好的开始:

这是asp.net 5dependency injection的官方文档。

dependency injection现在内置于asp.net 5中,但您可以自由使用其他库,如autofac。 默认的一个对我来说很好。

在你的starup类中,你有一个像这样的方法

 public void ConfigureServices(IServiceCollection services) { //IServiceCollection acts like a container and you //can register your classes like this: services.AddTransient(); services.Singleton(); services.AddScoped(); } 

从:

DependencyResolver Asp.net 5.0

这是在.Net core 2.0中为我工作的方式

 public ViewResult IndexWithServiceLocatorPattern([FromServices]ProductTotalizer totalizer) { var repository = (IRepository)HttpContext.RequestServices.GetService(typeof(IRepository)); ViewBag.HomeController = repository.ToString(); ViewBag.Totalizer = totalizer.repository.ToString(); return View("Index", repository.Products); } 

如果我必须用经典的方式来做,那就像下面。

 public class HomeController : Controller { private readonly IRepository repo; ///  /// MVC receives an incoming request to an action method on the Home controller. /// MVC asks the ASP.NET service provider component for a new instance of the HomeController class. /// The service provider inspects the HomeController constructor and discovers that it has a dependency on the IRepository interface. /// The service provider consults its mappings to find the implementation class it has been told to use for dependencies on the IRepository interface. /// The service provider creates a new instance of the implementation class. /// The service provider creates a new HomeController object, using the implementation object as a constructor argument. /// The service provider returns the newly created HomeController object to MVC, which uses it to handle the incoming HTTP request. ///  ///  public HomeController(IRepository repo) { this.repo = repo; } ///  /// Using Action Injection /// MVC uses the service provider to get an instance of the ProductTotalizer class and provides it as an /// argument when the Index action method is invoked.Using action injection is less common than standard /// constructor injection, but it can be useful when you have a dependency on an object that is expensive to /// create and that is required in only one of the action methods defined by a controller ///  ///  ///  public ViewResult Index([FromServices]ProductTotalizer totalizer) { ViewBag.Total = totalizer.repository.ToString(); ViewBag.HomeCotroller = repo.ToString(); return View(repo.Products); } }