在ASP.NET MVC中,可以通过DependencyResolver.Current.GetService<T>()
获得一些依赖关系。 ASP.NET Core中有类似的东西吗?
答案 0 :(得分:11)
是的,有。在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
答案 1 :(得分:8)
如果你真的需要它,你可以自己写一个。首先 - 创建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<T>()
{
return _serviceProvider.GetService<T>();
}
private AppDependencyResolver(IServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider;
}
}
请注意_serviceProvider.GetService<T>();
仅在您添加using Microsoft.Extensions.DependencyInjection;
时才可用。如果您向"Microsoft.Extensions.DependencyInjection": "1.0.0"
添加project.json
,则可以使用该命名空间。
您应该在Init
课程中调用startup
方法。例如
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
AppDependencyResolver.Init(app.ApplicationServices);
//all other code
之后,您可以在任何地方使用它,与DependencyResolver.Current
相同。但我的建议 - 只有在没有其他选择的情况下才使用它。
答案 2 :(得分:2)
Asp.net核心提供的服务,在HttpContext
this.HttpContext.RequestServices
通过使用此服务,可以获得服务。您还可以使用GetService方法通过指定依赖项的类型来检索依赖项:
this.HttpContext.RequestServices.GetService(typeof(ISomeService));
答案 3 :(得分:1)
IServiceProvider有扩展方法:GetService,GetRequiredService和GetServices。所有都有通用和非通用版本。 在Asp.Net Core Web项目中,您可以通过DI或IApplicationBuilder获取对IServiceProvider的引用。 在Console应用程序中,您应该创建自己的IServiceProvider实例并在某处存储引用
wp_list_categories(array('title_li' => false, 'style' => false));
答案 4 :(得分:1)
以下是.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;
/// <summary>
/// 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.
/// </summary>
/// <param name="repo"></param>
public HomeController(IRepository repo)
{
this.repo = repo;
}
/// <summary>
/// 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
/// </summary>
/// <param name="totalizer"></param>
/// <returns></returns>
public ViewResult Index([FromServices]ProductTotalizer totalizer)
{
ViewBag.Total = totalizer.repository.ToString();
ViewBag.HomeCotroller = repo.ToString();
return View(repo.Products);
}
}
答案 5 :(得分:0)
我认为这可能是一个好的开始:
这是asp.net 5依赖注入的官方文档。
依赖注入现在内置于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<IEmailSender, AuthMessageSender>();
services.Singleton<ISmsSender, AuthMessageSender>();
services.AddScoped<ICharacterRepository, CharacterRepository>();
}
自:
答案 6 :(得分:0)
我也想添加到主要答案中, 在razor视图页面中,我们可以对DI使用@inject指令。它将检索目标服务以在Asp.Net core上查看页面,像这样
@inject XYZ.Web.Services.CurrencyService currencyService;