【问题标题】:Unity IoC and Static methodUnity IoC 和静态方法
【发布时间】:2011-02-01 23:36:51
【问题描述】:

在您使用 IoC 但其中包含静态方法以及其他方法的情况下,最好的方法是什么,如下所示:

public partial class ShoppingCart
{
    private IDatabaseFactory _storeDB;

    public ShoppingCart(IDatabaseFactory storeDB)
    {
        _storeDB = storeDB;
    }

    private string ShoppingCartId { get; set; }

    public static ShoppingCart GetCart(HttpContextBase context)
    {
        var cart = new ShoppingCart(WHATGOESHERE?);
        cart.ShoppingCartId = cart.GetCartId(context);
        return cart;
    }

    public int OtherMethod()
    {
        ...
    }
}

【问题讨论】:

  • 为什么你的HttpContext 被传递到 DAL 层?
  • 我正在使用样本中的 sn-p。
  • 正如 Daniel A White 所指出的,这是个坏主意。 IoC 有时会暴露出这样的坏主意。

标签: c# unity-container ioc-container ninject


【解决方案1】:

静态GetCart 方法是Ambient Context。这是一个坏主意,尤其是在域模型级别有​​这样的方法。尝试将其重构为抽象工厂:

public interface IShoppingCartFactory
{
    ShoppingCart GetCartForCurrentUser();
}

您可以在需要它的服务中注入IShoppingCartFactory(但不能在您的实体中,最好保持您的实体干净)。现在您可以定义一个实现并将其注册到您的 IoC 配置中。以下是此类实现的示例:

public class HttpShoppingCartFactory : IShoppingCartFactory
{
    private readonly IShoppingUnitOfWorkFactory uowFactory;

    public HttpShoppingCartFactory(
        IShoppingUnitOfWorkFactory uowFactory)
    {
        this.uowFactory = uowFactory;
    }

    public ShoppingCart GetCartForCurrentUser()
    {
        int userId = (int)HttpContext.Current.Session["userId"];

        using (var unitOfWork = this.uowFactory.CreateNew())
        {
            return unitOfWork.ShoppingCards
                .FirstOrDefault(c => c.User.Id == userId);
        }
    }
}

将获取用户上下文与购物卡工厂分开会更好。例如,您可以在购物卡工厂中注入IUserContextFactory,使其独立于 ASP.NET。

【讨论】:

    【解决方案2】:

    IMO 你应该重构它,让它看起来像这样:

    public class ShoppingCartService {
        private readonly IDatabaseFactory _storeDB;
    
        public ShoppingCartService(IDatabaseFactory storeDB) {
            _storeDB = storeDB
        }
    
        public ShoppingCart GetCart(IdType cartId)
        {
            var cart = new ShoppingCart(_storeDB);
            cart.ShoppingCartId = cartId;
            return cart;
        }
    }
    
    public partial class ShoppingCart
    {
        private IDatabaseFactory _storeDB;
    
        public ShoppingCart(IDatabaseFactory storeDB)
        {
            _storeDB = storeDB;
        }
    
        private string ShoppingCartId { get; set; }
    
        public int OtherMethod()
        {
            ...
        }
    }
    

    这样,您将负责将当前购物车从静态方法转移到可以在表示层中注入的服务类。

    【讨论】:

      猜你喜欢
      • 2010-12-27
      • 1970-01-01
      • 1970-01-01
      • 2018-06-14
      • 1970-01-01
      • 2011-02-01
      • 2020-12-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多