首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >ASP.Net核心从另一个控制器调用控制器

ASP.Net核心从另一个控制器调用控制器
EN

Stack Overflow用户
提问于 2016-01-23 12:41:52
回答 6查看 71.6K关注 0票数 52

在我的ASP.Net Core 6解决方案中,我有两组控制器。其中一组包含有其常规视图的网页。另一组包含API控制器。

为了避免重复db逻辑,web控制器正在使用API控制器。目前,我正在手动创建所需控制器的实例,方法是将DbContext作为构造函数参数传递给它。这是通过依赖注入给web控制器的DbContext。

但是,每当我向API控制器添加另一个构造函数参数时,我就需要修改使用这个API控制器的所有web控制器。

如何使用内置到ASP.Net 5的依赖注入系统为我创建所需API控制器的实例?然后它将自动填写所需的构造函数参数。

一种解决方案可以是将db逻辑从API控制器移到一个单独的层,并从API和web控制器调用它。这不会解决我的问题,因为新的层仍然需要相同的参数,我不喜欢不必要的布线。

另一种解决方案是让网络控制器通过网络调用访问API,但这只会增加应用程序的复杂性。

今天我要做的是:

代码语言:javascript
运行
复制
public IActionResult Index()
{
    using (var foobarController = new Areas.Api.Controllers.FoobarController(
        // All of these has to be in the constructor of this controller so they can be passed on to the ctor of api controller
        _dbContext, _appEnvironment, 
        _userManager, _roleManager, 
        _emailSender, _smsSender))
    {
        var model = new IndexViewModel();
        model.Foo = foobarController.List(new FoobarRequest() { Foo = true, Bar = false });
        model.Bar = foobarController.List(new FoobarRequest() { Foo = false, Bar = true });
        return View(model);
    }
}

我希望有这样的东西:(这个例子不起作用)

代码语言:javascript
运行
复制
using (var foobarController = CallContextServiceLocator.Locator.ServiceProvider.GetService<Areas.Api.Controllers.FoobarController>())
{
    var model = new IndexViewModel();
    model.Foo = foobarController.List(new FoobarRequest() { Foo = true, Bar = false });
    model.Bar = foobarController.List(new FoobarRequest() { Foo = false, Bar = true });
    return View(model);
}
EN

回答 6

Stack Overflow用户

回答已采纳

发布于 2016-01-28 08:15:42

要能够使用来自另一个控制器的控制器,您需要:

  1. 在Startup.cs ConfigureServices:services.AddTransient <Areas.Api.Controllers.FoobarController, Areas.Api.Controllers.FoobarController>();中注册控制器
  2. 必须将要作为ctor参数访问的控制器传递到主控制器。

如果您需要访问控制器(如UserUrl )中的本地属性,则有两种方法可以这样做。

第一种方法是使用DI获取IHttpContextAccessor的一个实例来访问User,使用IUrlHelper来访问Url对象:

代码语言:javascript
运行
复制
public class FoobarController : Controller
{
    private readonly ApplicationDbContext _dbContext;
    private readonly IHttpContextAccessor _httpContextAccessor;
    private readonly IUrlHelper _urlHelper;
    public FoobarController(ApplicationDbContext dbContext, IHttpContextAccessor httpContextAccessor, IUrlHelper _urlHelper, [...])
    {
         _dbContext = dbContext;
         _httpContextAccessor = httpContextAccessor;
         _urlHelper = urlHelper;
    }

    public FoobarResponse List(FoobarRequest request)
    {
        var userId = _httpContextAccessor.HttpContext.User.GetUserId();
        var response = new FoobarResponse();
        response.List = _dbContext.Foobars.Where(f => f.UserId == userId).ToList();
        response.Thumb = 
        return response;
    }
}

第二种方法是在调用控制器中设置它:

代码语言:javascript
运行
复制
public class HomeController : Controller
{
    private Areas.Api.Controllers.FoobarController _foobarController;
    public HomeController(Areas.Api.Controllers.FoobarController foobarController)
    {
        _foobarController = foobarController;
    }

    private void InitControllers()
    {
        // We can't set this at Ctor because we don't have our local copy yet
        // Access to Url 
        _foobarController.Url = Url;
        // Access to User
        _foobarController.ActionContext = ActionContext;
        // For more references see https://github.com/aspnet/Mvc/blob/6.0.0-rc1/src/Microsoft.AspNet.Mvc.ViewFeatures/Controller.cs
        // Note: This will change in RC2
    }

    public IActionResult Index()
    {
        InitControllers();

        var model = new IndexViewModel();
        model.Foo = _foobarController.List(new FoobarRequest() { Foo = true, Bar = false });
        model.Bar = _foobarController.List(new FoobarRequest() { Foo = false, Bar = true });
        return View(model);
    }
}

ASP.Net核心MVC6 RC1控制器的源代码可以找到这里。然而,它正在对RC2进行大量重写,因此必须复制的属性才能访问用户和Url。

票数 18
EN

Stack Overflow用户

发布于 2018-03-19 21:31:33

如何使用内置到ASP.Net 5的依赖注入系统为我创建所需API控制器的实例?

在您的Startup.cs中,可以告诉MVC注册所有的作为服务的控制器

代码语言:javascript
运行
复制
services.AddMvc().AddControllersAsServices();

然后,您可以通过DI机制将所需的控制器简单地注入到其他控制器中,并调用其操作方法。

票数 43
EN

Stack Overflow用户

发布于 2016-01-25 14:10:35

不要这样做。将该逻辑移动到另一个组件,该组件将在两个控制器之间共享。作为HTTP调用的结果,控制器由框架分派到,它不是您的公共API表面。通常,您的控制器应该用作将HTTP请求转换为业务对象的位置。对这些对象的操作应该委托给另一个层(特别是如果需要从应用程序中的多个位置使用它)。

票数 37
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34963586

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档