c#-4.0 - 这是从域模型中实例化具有依赖关系的对象的正确方法吗?

标签 c#-4.0 domain-driven-design inversion-of-control domain-data-modelling

我试图避免以贫乏的域模型结束,所以我试图在域模型本身中保留尽可能多的逻辑。我有一个名为 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 ,因此域有能力使用自己的接口(interface),而无需查看具体的类实现:
 ServiceLocator.Factory = new IoCFactory();

我很确定我做错了什么,因为这一切都感觉有点像笨蛋。
  • 谁能发现任何明显的错误?
  • 是否有更合适的方式来实例化业务规则处理程序,例如 GetIngredient没有对我的 IoC 工厂的静态引用?
  • 最佳答案

    我建议你在设计中引入另一层——应用层。该层的职责是将命令(显式封装在命令对象中或隐式传递为 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
            });
        }
    }
    

    希望有帮助。

    关于c#-4.0 - 这是从域模型中实例化具有依赖关系的对象的正确方法吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3709972/

    相关文章:

    c# - 取消长时间运行的任务后如何正确清理

    domain-driven-design - 事件源系统中的流聚合关系

    asp.net-mvc - .NET 系统架构设计中涉及多个模型和聚合的良好实践是什么

    asp.net - “检测到 Autofac 循环组件依赖性”错误

    asp.net-mvc - 洋葱架构我们应该将领域模型注入(inject)表示层吗?

    .net - 使用 .net 连接器连接 Couchbase 服务器时出现异常

    c# - 如何使用具有相同契约(Contract)和绑定(bind)的动态端点创建多个 wcf 服务实例而不保存在 app.config 中?

    c#-4.0 - C# 中的 Activator.CreateInstance 和泛型方法

    java - 域抽象中的 Bean 验证

    logging - 温莎城堡 : Best way to log when a component is registered?