【问题标题】:ASP.NET MVC - Best practices when passing dependenciesASP.NET MVC - 传递依赖项时的最佳实践
【发布时间】:2020-08-07 01:30:32
【问题描述】:

我有一个问题,我试图通过 Google 搜索,但老实说,我真的不知道如何搜索甚至问这个特定问题。

假设我有以下内容:

控制器


        [HttpGet]
        public virtual ActionResult Summary()
        {
            var summaryViewModel = new CheckoutSummaryViewModel()
            {
                Products = ProductViewModel.BuildListFromShoppingCart(GetShoppingCart())
            };
            return View("_Summary", summaryViewModel);
        }

ProductViewModel

    public class ProductViewModel
    {
        public string Name
        {
            get; set;
        }

        public static List<ProdutoCheckoutViewModel> BuildListFromShoppingCart(ShoppingCart shoppingCart, IMappingService mappingService)
        {
            var itemsInCart = new List<ProductViewModel>();
            foreach (var item in shoppingCart.ItemsInCart)
            {
                var itemViewModel = mappingService.Map<Product, ProductViewModel>(item.Product);
                itemViewModel.Quantidade = item.Quantity;
                itemsInCart.Add(itemViewModel);
            }

            return itemsInCart;
        }
    }

这不是生产代码。只是这样我可以解释我的意思。

这是正确的做法吗?

  1. 有没有比使用 static 构建列表更好的方法?我真的不想在控制器内部这样做。
  2. 将 IMappingService 传递给该方法看起来不正确。但也许我只是挑剔。这是最好的方法吗?

另一种情况,我需要将会话状态传递给静态帮助程序类。

        public static Guid GetCheckoutId(HttpSessionStateBase session)
        {
            return (Guid)session["checkoutId"];
        }

或者,有时我需要作为参数传递给辅助方法,我的“unifOfWork”,因为我使用存储库模式。

我经常遇到这个“问题”,但我还没有找到最好的方法来解决这个问题。

PS:如果你们中有人对这个问题有更好的标题,请告诉我,以便我更新它。

【问题讨论】:

  • 您可能需要研究依赖注入和 IoC 容器(控制反转)以获得所需的功能。通常,您希望避免使用静态,因为它们不容易进行单元测试。至于会话,我想说控制器应该进入会话并提取您需要的数据并将其传递给下一层。这将是控制器的责任。
  • 我使用 Ninject 作为工作单元和映射服务,但我可能会在 DI 中找到答案。关于会议,是的,这是有道理的......
  • IoC 容器,如 Ninject,是 DI 的全部内容。让我们看看我是否可以在下面通过代码示例正确回答您。

标签: c# asp.net asp.net-mvc-5 architecture


【解决方案1】:

控制器 如果你使用 DI,它看起来像这样:

public class CheckoutController 
{
    private readonly ICheckoutService _checkoutService;

    public CheckoutController(ICheckoutService checkoutService) =>
        _checkoutService = checkoutService;

    [HttpGet]
    public virtual ActionResult Summary()
    {
        var shoppingCartData = _checkoutService.GetShoppingCart(Session["..."]);
        // The viewmodel here could be returned by your service or the service
        // would return all required data and the viewmodel simply transforms that Dto into what is needed by the UI

        var summaryViewModel = new CheckoutSummaryViewModel()
        {
            Products = shoppingCartData 
        };
        return View("_Summary", summaryViewModel);
    }

}

【讨论】:

  • 感谢您的回答!自从您指出后,我一直在研究 DI 和 IoC。现在我明白了,这正是我想要的。
  • DI 和 IoC 起初可能看起来有点吓人,但实际上它只是使用一些接口并告诉应用程序如何在顶部创建该实例 - 现在您可以随时对代码进行单元测试! :)
  • 是的!在过去的几个月里,我的表现越来越好,现在看起来不再那么可怕了。我也很容易对所有内容进行单元测试。非常感谢您的帮助。
猜你喜欢
  • 2011-10-15
  • 2015-03-10
  • 2019-08-24
  • 2011-08-16
  • 1970-01-01
  • 2020-10-22
  • 2018-03-03
  • 2010-11-14
  • 1970-01-01
相关资源
最近更新 更多