【问题标题】:ASP.Net Core DI Factory Based on HttpContext基于 HttpContext 的 ASP.Net Core DI 工厂
【发布时间】:2017-05-04 13:24:29
【问题描述】:

我希望 ASP.Net Core IoC 容器根据当前显示的视图提供接口的实现。我认为我应该能够通过提供工厂方法在运行时做到这一点。在Startup.cs我添加了以下注册:

services.AddTransient<IMyInterface>(serviceProvider => 
{
    var context = serviceProvider.GetRequiredService<IHttpContextAccessor>().HttpContext;

    //Need to switch on current view somehow?
    switch(context.??????){
        case ???:
             return new MyImplementationOne();
        case ???:
             return new MyImplementationTwo():

    }

}

如何使用HttpContext 根据当前显示的视图进行切换?或者,我应该使用serviceProvider 提供的其他服务吗?

【问题讨论】:

  • 您是否尝试过使用请求 URL?在执行控制器操作并返回视图结果之前,我们无法知道将显示哪个视图。到那时,所有的依赖关系都必须已经解决了。
  • @juunas 我是新手:如何获取请求 URL? context.Request 上似乎没有 URL 属性?
  • 有一个Path 属性。
  • 您可以使用IActionContextAccessor 接收一个包含正在执行的控制器和动作的ActionContext 实例。
  • 不幸的是Path 属性只返回"\"????

标签: c# dependency-injection asp.net-core


【解决方案1】:

通常你会在你的 DI 容器中注册一个“工厂”,例如 IWhateverServiceFactory...

这将有一个方法,它接受视图名称(您可以从 RouteContext 获取)并返回相关的实现。通过这种方式,您可以轻松更改关于哪个实现的逻辑,例如,如果您希望在将来的某个时间使用通用实现。

public interface IWhateverServiceFactory{
    IService GetService(String currentViewName);
}

public class DefaultWhateverServiceFactory : IWhateverServiceFactory{
    IService GetService(String currentViewName){
        switch(currentViewName){
        case ???:
             return new MyImplementationOne();
        case ???:
             return new MyImplementationTwo():
        }
    }
}

RouteContext 对你不起作用,你可以使用类似的东西;

System.IO.Path.GetFileNameWithoutExtension(
            ((RazorView)html.ViewContext.View).ViewPath
        );

如果您使用 Razor 获取视图名称,或者

Html.ViewContext.RouteData.GetRequiredString("action");

获取动作名称...

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-07-20
    • 1970-01-01
    • 2021-05-05
    • 2020-06-09
    • 1970-01-01
    • 1970-01-01
    • 2020-09-22
    • 2016-05-26
    相关资源
    最近更新 更多