【问题标题】:AspNet Core : how to get current controller object in a serviceAspNet Core:如何在服务中获取当前控制器对象
【发布时间】:2018-10-09 18:25:49
【问题描述】:

我构建了一个 .NetCore 2.1 项目并有一个像这样的基本控制器类

public class MyBaseController:Controller
{
    #region Properties

    protected readonly ILogger Logger;
    protected readonly VVDCCore.Tools.Interfaces.IResourceManager Resx; 

    protected IDictionary<string,string> ExtraParameters;

    #endregion

    #region CONSTRUCTOR

    public BaseController(ILogger<BaseController> logger,
        VVDCCore.Tools.Interfaces.IResourceManager resxManager)
    {
        Logger = logger;
        Resx = resxManager;
    }

    #endregion
}

我所有的控制器都是这个基类的子类。

我有一个服务(实现 IResourceManager 接口的 ResourceServices),它允许根据键和上下文检索值。

感谢 IActionContextAccessor 接口,我知道如何在服务中访问控制器的名称和操作的名称。 但我想获得当前的控制器对象。 在服务中,我需要从我的 baseController 访问属性 ExtraParameters 但不知道该怎么做

总而言之,我想做这样的事情

public class ResourcesServices{

    public ResourceServices([CurrentController] controller)
    {
        var extraParameters = ((MyBaseController)controller).ExtraParameters;
    }
}

有什么办法吗? TIA

【问题讨论】:

  • 你可以做一个简单的类型转换。但这是一个可疑的设计,服务不需要知道(依赖)它的调用者。因为这是一个循环依赖。不能把相关数据作为参数传递吗?

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


【解决方案1】:

不要将控制器对象引用到其他类。
而是只提供类所需的信息。

public class ResourcesServices
{
    public ResourceServices(IDictionary<string, string> parameters)
    {
        var extraParameters = parameters;
    }
}

如果您正在使用依赖注入并且ExtraParameters 仅在运行时已知(ResourcesServices 实例无法实例化)。
然后考虑将参数传递给ResourcesServices的方法,该方法将使用它们。

public class ResourcesServices
{        
    public ResourceServices() { }

    public void DoSomething(IDictionary<string, string> parameters)
    {
        var extraParameters = parameters;
    }
}

ResourceServices 类需要在构造函数中提供“ExtraParameters”时,您可以创建工厂类,该类将负责创建具有运行时值的ResourceServices 的正确实例。

public class ResourcesServicesFactory
{        
    public ResourcesServicesFactory() { }

    public ResourcesServices Create(IDictionary<string, string> parameters)
    {
        return new ResourcesServices(parameters);
    }
}   

public class ChildController : MyBaseController
{
    private readonly ResourceServiceFactory _factory;


    public ChildController(  
        ILogger<BaseController> logger,
        VVDCCore.Tools.Interfaces.IResourceManager resxManager,
        ResourceServiceFactory factory) : base(logger, resxManager)
    {
        _factory = factory;
    }

    public IActionResult Get()
    {
        var service = _factory.Create(ExtraParameters);
        service.DoSomething();
    }
}

将控制器视为应用程序的入口点,其主要职责将“输入”传递给服务并将输出返回给客户端。

【讨论】:

  • 非常感谢您的回答。对我来说,工厂似乎是最好/最干净的解决方案,非常感谢
猜你喜欢
  • 2017-11-22
  • 2016-12-16
  • 1970-01-01
  • 2017-05-04
  • 2018-01-07
  • 1970-01-01
  • 1970-01-01
  • 2011-05-19
  • 1970-01-01
相关资源
最近更新 更多