Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 基于HttpContext的ASP.Net核心DI工厂_C#_Dependency Injection_Asp.net Core - Fatal编程技术网

C# 基于HttpContext的ASP.Net核心DI工厂

C# 基于HttpContext的ASP.Net核心DI工厂,c#,dependency-injection,asp.net-core,C#,Dependency Injection,Asp.net Core,我希望ASP.Net核心IoC容器根据当前显示的视图提供接口的实现。我想我应该能够在运行时通过提供工厂方法来实现这一点。在Startup.cs中,我添加了以下注册: services.AddTransient<IMyInterface>(serviceProvider => { var context = serviceProvider.GetRequiredService<IHttpContextAccessor>().HttpContext;

我希望ASP.Net核心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():

    }

}
services.AddTransient(serviceProvider=>
{
var context=serviceProvider.GetRequiredService().HttpContext;
//需要以某种方式打开当前视图吗?
切换(上下文){
案例??:
返回新的MyImplementationOne();
案例??:
返回新的MyImplementationTwo():
}
}

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

通常,您会在DI容器中注册一个“工厂”,例如iWhaterServiceFactory

这将有一个方法,它接受视图名称(您可以从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");

要获取操作名称…

通常,您需要在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");

要获取操作名称…

您是否尝试过使用请求URL?在执行控制器操作并返回视图结果之前,我们不知道将显示哪个视图。此时,所有依赖项都必须已解决。@juunas我是新手:如何获取请求URL?
上下文。请求
不会出现r是否有
URL
属性?有一个
Path
属性。您可以使用
IActionContextAccessor
接收一个
ActionContext
实例,其中包含正在执行的控制器和操作。不幸的是
Path
属性只返回
“\”
???您是否尝试过使用请求URL?在执行控制器操作并返回视图结果之前,我们不知道将显示哪个视图。此时,所有依赖项都必须已解决。@juunas我不熟悉:如何获取请求URL?
上下文。请求
似乎没有
URL
属性?有一个
路径
属性。您可以使用
IActionContextAccessor
来接收一个
操作上下文
实例,其中包含正在执行的控制器和操作。不幸的是
路径
属性只返回
“\”
????