2

我试图避免结束一个贫血的域模型,所以我试图在域模型本身内保留尽可能多的逻辑。我有一个名为AddIngredient的方法,它需要为我的Recipe总计添加一个新的KeyedObject这是从域模型中实例化具有依赖关系的对象的正确方法吗?

为域模型本身的意思是没有仓库的,我通过业务规则获得成分类:

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,因此域必须使用自己的接口,没有看到具体类实现的功能:

ServiceLocator.Factory = new IoCFactory(); 

我很确定我做错了什么,因为它所有的感觉都有点像鲍奇一样。

  • 任何人都可以发现任何公然错误的东西吗?
  • 是否有更适当的方法来实例化业务规则处理程序,例如GetIngredient而没有对IoC工厂的静态引用?

回答

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

而且现在简化配方类将是这个样子:

public class Recipe : AggregateObject 
{ 
    public void AddIngredient(Ingredient ingredient, double quantity) 
    { 
     Ingredients.Add(new OriginalIngredient() 
     { 
      Ingredient = ingredient, 
      Quantity = quantity 
     }); 
    } 
} 

希望有所帮助。

+0

Arrr!发现。这是一个完全愚蠢的时刻。我的域模型中的其他任何地方都添加了对象模型,而不是通过ID。所以这个答案基本上可以概括为:“你必须添加对象模型到你的域模型中,而不是通过一个ID添加”。这更有意义。正确? – GenericTypeTea 2010-09-15 08:17:02

+0

@GenericTypeTea并非总是如此。有时候Id就足够了。但是这里真正的问题是Szymon很好地解决了域模型中的基础设施逻辑以及相当直接的域模型对持久性的认识。 – 2010-09-17 14:44:24

相关问题