2

我试图避免以贫乏的域模型结束,所以我试图在域模型本身中保留尽可能多的逻辑。我有一个名为 的方法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 工厂的静态引用?
4

1 回答 1

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

希望有帮助。

于 2010-09-15T05:16:18.780 回答