ASP.NET Core DependencyResolver

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

  • 它在 RC2 中被删除 https://github.com/aspnet/Announcements/issues/118 (2认同)

Yur*_*iyP 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;
    }
} 
Run Code Online (Sandbox Code Playgroud)

请注意,_serviceProvider.GetService<T>();仅在您添加时才可用using Microsoft.Extensions.DependencyInjection;.如果您添加"Microsoft.Extensions.DependencyInjection": "1.0.0"到您的名称空间,该名称空间将可用project.json.比你应该Initstartup课堂上调用方法.例如

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

之后你就可以在任何地方使用它,就像它一样DependencyResolver.Current.但我的建议 - 只有在没有其他选择的情况下才使用它.


Bha*_*rat 7

这是在 .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)


Des*_*rif 0

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

这是 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