我正在努力避免陷入贫血的域模型,所以我试图在域模型本身中保留尽可能多的逻辑。我有一个名为AddIngredient
的方法,需要向我的KeyedObject
聚合添加新的Recipe
。
由于域模型本身意味着没有存储库,我通过业务规则类获取该成分:
public class Recipe : AggregateObject
{
public void AddIngredient(int ingId, double quantity)
{
GetIngredientMessage message = new GetIngredientMessage();
message.IngredientId = ingId;
GetIngredient handler = ServiceLocator.Factory.Resolve<GetIngredient>();
Ingredient ingredient = handler.Execute(message);
Ingredients.Add(new OriginalIngredient()
{
Ingredient = ingredient,
Quantity = quantity
});
}
}
正如您所看到的,我正在使用第ServiceLocator.Factory.Resolve<GetIngredient>();
行来获取我的GetIngredient
业务规则类。 GetIngredient
是一个简单的命令处理程序,如下所示:
public class GetIngredient : ICommandHandler<Ingredient, GetIngredientMessage>
{
private readonly IIngredientRepository _ingredientRepository;
public GetIngredient(IIngredientRepository ingredientRepository)
{
_ingredientRepository = ingredientRepository;
}
}
我将IoC工厂类分配给ServiceLocator.Factory
,因此Domain可以使用自己的接口,而无需查看具体的类实现:
ServiceLocator.Factory = new IoCFactory();
我很确定我做错了什么,因为它感觉有点像波澜一样。
GetIngredient
而没有对IoC Factory的静态引用?答案 0 :(得分:3)
我建议你在设计中引入另一层 - 应用层。该层的职责是将命令(显式封装在命令对象中或隐式传递为int ingId, double quantity
)转换为域模型调用(Recipe.AddIngredient
)。
通过这样做,您将负责通过其ID查找成分到域上方的层,您可以安全地直接使用存储库而不会引入不需要的耦合。转换后的解决方案看起来像这样:
public class ApplicationLayer
{
private readonly IRecipeRepository _recipeRepository;
private readonly IIngredientRepository _ingredientRepository;
/*
* This would be called by IoC container when resolving Application layer class.
* Repositories would be injected by interfacy so there would be no coupling to
* concrete classes.
*/
public ApplicationLayer(IRecipeRepository recipeRepository, IIngredientRepository ingredientRepository)
{
_recipeRepository = recipeRepository;
_ingredientRepository = ingredientRepository;
}
public void AddIngredient(int recipeId, int ingId, double quantity)
{
var recipe = _recipeRepository.FindById(recipeId);
var ingredient = _ingredientRepository.FindById(ingId);
recipe.AddIngredient(ingredient, quantity);
}
}
现在简化的Recipe类看起来像这样:
public class Recipe : AggregateObject
{
public void AddIngredient(Ingredient ingredient, double quantity)
{
Ingredients.Add(new OriginalIngredient()
{
Ingredient = ingredient,
Quantity = quantity
});
}
}
希望有所帮助。