Datas-project 和 Builders-project 之间的循环依赖
Cyclic dependency between Datas-project and Builders-project
这里是我想要实现的代码:
- A
Character
has strength
, constitution
, and some other stats.
- Each
Character
has BaseStats
depending of his class.
- Each
Character
has RandomStats
bonus, with positive values from 0 to 3.
- A stat may not be lower than 1, nor higher than 10.
- A
Character
may have Bonus
and Malus
in their stats.
- If a
Character
has 8 in strength
, plus a bonus of 4, and a malus of 1, he finally has 10 (8+4-1=11 > 10).
- If a
Character
has 3 in constitution, plus a bonus of 1, and a malus of 4, he finally has 1 (3+1-4=0 < 1).
在我的 .NET 解决方案中,我尝试将 datas
和 builders
分开放在不同的项目中。目前,我的 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<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),
/* ... */
);
}
}
}
我的问题如下:
My builders
project references my datas
project.
ERROR: I want to add a FinalStats
property in my Character
class. This FinalStats
should use my EntityStatsBuilder
class. Then, my datas
project should reference my builders
project.
public EntityStats FinalStats
{
get
{
EntityStatsBuilder builder = new EntityStatsBuilder();
builder.Add(BaseStats);
builder.Add(RandomStats);
return builder.ToStats();
}
}
我应该如何修改我的全局架构才能避免这种循环依赖?
你要找的就是所谓的依赖倒置原则https://en.wikipedia.org/wiki/Dependency_inversion_principle
基本上为您的 EntityStatsBuilder
创建一个界面并将其放在一个单独的项目中。
现在两个项目都可以引用该接口项目。如果要遵循 Microsoft 命名约定,请将其命名为 SomethingSomething.Abstractions
.
现在,在使用依赖项注入的启动项目中,您在 Character
对象中注入了一个具体的 EntityStatsBuilder
。为此,您可以根据需要使用 DI 框架或简单的构造函数注入。
这里是我想要实现的代码:
- A
Character
hasstrength
,constitution
, and some other stats.- Each
Character
hasBaseStats
depending of his class.- Each
Character
hasRandomStats
bonus, with positive values from 0 to 3.- A stat may not be lower than 1, nor higher than 10.
- A
Character
may haveBonus
andMalus
in their stats.- If a
Character
has 8 instrength
, plus a bonus of 4, and a malus of 1, he finally has 10 (8+4-1=11 > 10).- If a
Character
has 3 in constitution, plus a bonus of 1, and a malus of 4, he finally has 1 (3+1-4=0 < 1).
在我的 .NET 解决方案中,我尝试将 datas
和 builders
分开放在不同的项目中。目前,我的 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<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),
/* ... */
);
}
}
}
我的问题如下:
My
builders
project references mydatas
project.
ERROR: I want to add aFinalStats
property in myCharacter
class. ThisFinalStats
should use myEntityStatsBuilder
class. Then, mydatas
project should reference mybuilders
project.
public EntityStats FinalStats
{
get
{
EntityStatsBuilder builder = new EntityStatsBuilder();
builder.Add(BaseStats);
builder.Add(RandomStats);
return builder.ToStats();
}
}
我应该如何修改我的全局架构才能避免这种循环依赖?
你要找的就是所谓的依赖倒置原则https://en.wikipedia.org/wiki/Dependency_inversion_principle
基本上为您的 EntityStatsBuilder
创建一个界面并将其放在一个单独的项目中。
现在两个项目都可以引用该接口项目。如果要遵循 Microsoft 命名约定,请将其命名为 SomethingSomething.Abstractions
.
现在,在使用依赖项注入的启动项目中,您在 Character
对象中注入了一个具体的 EntityStatsBuilder
。为此,您可以根据需要使用 DI 框架或简单的构造函数注入。