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

相關問題