ana*_*ser 13 c# dependency-injection asp.net-core-mvc
在ASP.NET MVC 5中可以通过获得一些依赖DependencyResolver.Current.GetService<T>().ASP.NET Core中有类似的东西吗?
Ser*_*nte 15
就在这里.在ASP.NET Core 1.0.0中,请求中可用的服务HttpContext通过RequestServices集合[1]公开:
this.HttpContext.RequestServices
Run Code Online (Sandbox Code Playgroud)
您可以使用GetService方法通过指定依赖项的类型来检索依赖项:
this.HttpContext.RequestServices.GetService(typeof(ISomeService));
Run Code Online (Sandbox Code Playgroud)
通常,您不应该直接使用这些属性,而是更喜欢通过类的构造函数请求类所需的类,并让框架注入这些依赖项.这产生了更容易测试并且更松散耦合的类.
[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<T>()
{
return _serviceProvider.GetService<T>();
}
private AppDependencyResolver(IServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider;
}
}
Run Code Online (Sandbox Code Playgroud)
请注意,_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
Run Code Online (Sandbox Code Playgroud)
之后你就可以在任何地方使用它,就像它一样DependencyResolver.Current.但我的建议 - 只有在没有其他选择的情况下才使用它.
这是在 .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);
}
Run Code Online (Sandbox Code Playgroud)
如果我必须用经典的方式来做,它会像下面这样。
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);
}
}
Run Code Online (Sandbox Code Playgroud)
我认为这可能是一个好的开始:
这是 ASP.NET 5 依赖注入的官方文档。
依赖注入现已内置于 asp.net 5 中,但您可以自由使用其他库,例如 autofac。默认的对我来说效果很好。
在你的启动类中,你有这样的方法
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>();
}
Run Code Online (Sandbox Code Playgroud)
从:
DependencyResolver Asp.net 5.0
| 归档时间: |
|
| 查看次数: |
16627 次 |
| 最近记录: |