当我尝试实现状态模式时检测到循环依赖

问题描述 投票:0回答:1

我遇到这个问题:

System.InvalidOperationException:'检测到循环依赖 用于“LibraryExamples.Water.States.IGasState”类型的服务。 LibraryExamples.Water.IWater(LibraryExamples.Water.WaterMe) -> LibraryExamples.Water.IWaterStateFactory(LibraryExamples.Water.WaterStateFactory) -> LibraryExamples.Water.States.IGasState(LibraryExamples.Water.States.GasState) -> LibraryExamples.Water.States.ILiquidState(LibraryExamples.Water.States.LiquidState) -> LibraryExamples.Water.States.IGasState'

namespace LibraryExamples.Water.States
{
    public class GasState : IGasState
    {
        private readonly ILiquidState LiquidState;

        public GasState(ILiquidState nextState)
        {
            this.LiquidState = nextState;
        }

        public IWaterState Heat()
        {
            Console.WriteLine("Already in a gaseous state. Heating has no effect.");

            return this;
        }

        public IWaterState Cool()
        {
            Console.WriteLine("Cooling gas (steam) turns it into liquid water.");

            return this.ToLiquidState();
        }

        public void Describe()
        {
            Console.WriteLine("Current state: Gas");
        }

        public ILiquidState ToLiquidState()
        {
            return this.LiquidState;
        }
    }
}
namespace LibraryExamples.Water.States
{
    public interface IGasState : IWaterState
    {

        ILiquidState ToLiquidState();
    }
}
namespace LibraryExamples.Water.States
{
    public interface ILiquidState : IWaterState
    {
        IGasState ToGasState();
    }
}
namespace LibraryExamples.Water.States
{
    public interface ISolideState : IWaterState
    {
        ILiquidState ToLiquidState();
    }
}
namespace LibraryExamples.Water.States
{
    public class LiquidState : ILiquidState
    {
        private readonly IGasState GasState;

        private readonly ISolideState solideState;

        public LiquidState(IGasState GastState, ISolideState solideState)
        {
            this.GasState = GastState;
            this.solideState = solideState;
        }

        public IWaterState Cool()
        {
            Console.WriteLine("Cooling liquid water turns it into solid water.");

            return this.ToSolidState();
        }

        public IWaterState Heat()
        {
            Console.WriteLine("Heating liquid water turns into gas water");

            return this.ToGasState();
        }

        public void Describe()
        {
            Console.WriteLine("Current state: Solid");
        }

        public IGasState ToGasState()
        {
            return this.GasState;
        }

        public ISolideState ToSolidState()
        {
            return this.solideState;
        }
    }
}
namespace LibraryExamples.Water.States
{
    public class SolidState : ISolideState
    {
        private readonly ILiquidState LiquidState;

        public SolidState(ILiquidState liquidState)
        {
            this.LiquidState = liquidState;
        }

        public IWaterState Heat()
        {
            Console.WriteLine("Heating solid water turns it into liquid water.");

            return this.ToLiquidState();
        }

        public IWaterState Cool()
        {
            Console.WriteLine("Already solid. Cooling has no effect.");

            return this;
        }

        public void Describe()
        {
            Console.WriteLine("Current state: Solid");
        }

        public ILiquidState ToLiquidState()
        {
            return this.LiquidState;
        }
    }
}
namespace LibraryExamples.Water
{
    public interface IWater
    {
        void Cool();
        void DescribeState();
        void Heat();
    }
}
namespace LibraryExamples.Water
{
    public interface IWaterState
    {
        IWaterState Heat();
        IWaterState Cool();
        void Describe();
    }
}
namespace LibraryExamples.Water
{
    public class Water : IWater
    {
        private IWaterState State;

        public Water(IWaterState initialState)
        {
            this.State = initialState;
        }

        public void Heat()
        {
            this.State.Heat();
        }

        public void Cool()
        {
            this.State.Cool();
        }

        public void DescribeState()
        {
            this.State.Describe();
        }
    }
}

我遇到这个问题:

System.InvalidOperationException:'检测到循环依赖 对于“LibraryExamples.Water.States.IGasState”类型的服务。

c# dependency-injection dependencies state-pattern di-containers
1个回答
0
投票

为什么不同的状态需要不同的接口?每个聚合状态都应该实现相同的接口,以便您可以以相同的方式访问和使用它。

public interface IAggregateState
{
    IAggregateState? CoolerState { get; }
    IAggregateState? HotterState { get; }

    string Description { get; }
}

聚合状态引用了较冷和较热的状态,以便我们可以以逻辑方式将它们链接在一起。请注意,状态可以为空,因为最酷的状态没有前驱状态,而最热的状态没有后继状态。

除了描述之外,所有状态都有相同的实现。因此,我们将基状态实现为抽象类:

public abstract class AggregateState : IAggregateState
{
    public abstract string Description { get; }

    public IAggregateState? CoolerState { get; set; }

    public IAggregateState? HotterState { get; set; }
}

我们无法推导出不同的状态:

public class Solid : AggregateState
{
    public override string Description => "Aggregate state: Solid";
}
public class Liquid : AggregateState
{
    public override string Description => "Aggregate state: Liquid";
}

public class Gaseous : AggregateState
{
    public override string Description => "Aggregate state: Gaseous";
}

不仅水具有聚合态。因此,我没有声明一个接口

IWater
,而是声明一个更通用的接口:

public interface IMatter
{
    IAggregateState State { get; }
    void Heat();
    void Cool();
    string Name {  get; }
    string Description { get; }
}

在这里,对于不同种类的物质,只有名称会有所不同,并且描述应该是根据物质名称和当前聚合状态构建的。因此,我们再次将物质实现为抽象类:

public abstract class Matter(IAggregateState initialState) : IMatter
{
    public abstract string Name { get; }
    public string Description => $"{Name}: {State.Description}";

    public IAggregateState State { get; private set; } = initialState;

    public void Cool()
    {
        State = State.CoolerState ?? State;
    }

    public void Heat()
    {
        State = State.HotterState ?? State;
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.