Unity IoC 和静态方法

发布于 2024-10-15 06:19:46 字数 549 浏览 7 评论 0原文

处理使用 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()
    {
        ...
    }
}

What is the best way to handle a situation where you're using IoC but there is a static method in it along with the other methods like the following:

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()
    {
        ...
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

等风也等你 2024-10-22 06:19:46

静态 GetCart 方法是一个环境上下文。这是一个坏主意,尤其是在域模型级别使用这样的方法。尝试将其重构为抽象工厂:

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。

The static GetCart method is an Ambient Context. It's a bad idea, especially to have such a method at the level of your domain model. Try refactoring it to an abstract factory:

public interface IShoppingCartFactory
{
    ShoppingCart GetCartForCurrentUser();
}

You can inject the IShoppingCartFactory in services that need it (but not in your entities, it's better to keep your entities clean). Now you can define an implementation and register it in your IoC configuration. Here's an example of such an implementation:

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);
        }
    }
}

It would be even better to separate the getting the user context from the shopping card factory. For instance, you yould inject a IUserContextFactory in the shopping card factory, making it independant on ASP.NET.

油焖大侠 2024-10-22 06:19:46

在我看来,您应该重构它,使其看起来像这样:

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()
    {
        ...
    }
}

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

IMO you should refactor it, making it to look like this:

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()
    {
        ...
    }
}

This way, you are moving responsibility to get the current shopping cart from a static method to a service class you can inject in the presentation layer.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文