【问题标题】:Cyclic dependency between Datas-project and Builders-projectDatas-project 和 Builders-project 之间的循环依赖
【发布时间】:2019-03-21 20:43:39
【问题描述】:

这是我想要实现的代码:

  • Character 具有strengthconstitution 和其他一些统计信息。
  • 每个Character 都有BaseStats,具体取决于他的班级。
  • 每个Character 都有RandomStats 奖励,正值从0 到3。
  • 统计数据不得低于 1,也不得高于 10。
  • Character 的统计数据中可能有 BonusMalus
  • 如果Characterstrength 中有 8,再加上 4 的红利和 1 的除数,他最终有 10 (8+4-1=11 > 10)。
  • 如果Character 的体质为 3,加值为 1,正值为 4,则他最终为 1 (3+1-4=0

在我的 .NET 解决方案中,我尝试在不同的项目中分离 datasbuilders。目前,我的datas 项目中有这样的东西:

namespace Data.Entities.Characters
{
    public abstract class Character : Entity
    {
        public abstract EntityStats BaseStats { get; }
        public EntityStats RandomStats { get; }
    }
}

namespace Data.Stats
{
    public struct EntityStats
    {
        private Dictionary<EntityStat, int> _stats;
        public int this[EntityStat stat] { get { return _stats[stat]; } }

        public EntityStats(int strength, int constitution, /* ... */)
        {
            _stats = new Dictionary<EntityStat, int>();
            _stats.Add(EntityStat.Strength, strength);
            _stats.Add(EntityStat.Constitution, constitution);
            /* ... */
        }
    }
}

然后,我有一个 builder 和一个 List&lt;EntityStats

namespace Builder
{
    public class EntityStatsBuilder
    {
        private List<EntityStats> StatsList { get; set; }
        public EntityStatsBuilder() { StatsList = new List<EntityStats>(); }
        public void Add(EntityStats stats) { StatsList.Add(stats); }

        public EntityStats ToStats()
        {
            int strength = 0,
                constitution = 0, 
                /* ... */;

            foreach (EntityStats stats in StatsList)
            {
                strength += stats[EntityStat.Strength];
                constitution += stats[EntityStat.Constitution];
                /* ... */
            }

            // module FMath =
            //     let Clamp value min max =
            //         if value < min then min elif value > max then max else value
            return new EntityStats(
                FMath.Clamp(strength, 1, 10),
                FMath.Clamp(constitution, 1, 10),
                /* ... */
            );
        }
    }
}

我的问题如下:

我的builders 项目引用了我的datas 项目。
错误:我想在我的Character 类中添加一个FinalStats 属性。这个FinalStats 应该使用我的EntityStatsBuilder 类。然后,我的datas 项目应该引用我的builders 项目。

public EntityStats FinalStats
{
    get
    {
        EntityStatsBuilder builder = new EntityStatsBuilder();
        builder.Add(BaseStats);
        builder.Add(RandomStats);
        return builder.ToStats();
    }
}

我应该如何修改我的全局架构以避免这种循环依赖?

【问题讨论】:

  • 您是否考虑过使用接口并将其放入第三个共享程序集中?
  • 我不明白你的建议,你能说得更清楚些吗?谢谢
  • 现在你有 Assambly A 和 ClassA,使用来自程序集 B 的 ClassB,而后者又使用来自程序集 A 的 ClassA => 循环依赖。我通常的方法是创建接口并将它们放在共享程序集 C 中,因此您有:程序集 C:IntfA,IntfB,程序集 A:ClassA 使用 IntfB 实现 IntfA,程序集 B:ClassB 使用 IntfA 实现 IntfB,所以程序集 A而 B 只依赖于程序集 C。

标签: c# .net cyclic-dependency


【解决方案1】:

你要找的叫做依赖倒置原则https://en.wikipedia.org/wiki/Dependency_inversion_principle

基本上为您的EntityStatsBuilder 创建一个接口并将其放在一个单独的项目中。 现在两个项目都可以引用该接口项目。如果您想遵循 Microsoft 命名约定,请将其命名为 SomethingSomething.Abstractions

现在,在使用依赖注入的启动项目中,您在 Character 对象中注入具体的 EntityStatsBuilder。为此,您可以根据需要使用 DI 框架或简单的构造函数注入。

【讨论】:

  • Implementation 部分之后,接口应该在我的Data 项目中。我应该遵循什么解决方案?
猜你喜欢
  • 2016-06-27
  • 1970-01-01
  • 2020-12-20
  • 2011-11-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-08-19
  • 2019-02-04
相关资源
最近更新 更多