DDD和LookUp表

时间:2017-09-07 14:00:25

标签: c# model domain-driven-design

基线条件:

有一个带有许多固定参数的Bike模型。除了原始模型参数外,还应该可以手动添加新的模型参数。

情况:

数据库中的每个参数都由以下特征表示:

  • 参数名称
  • 单位
  • 参数值

数据库中有几个查找表。这些表中的每一个都显示了可用的度量单位。

在其他参考表中,显示参数的名称。

应为每个型号显示参数名称,其值和度量单位。

问题:

如何最好地实施基于DDD的这种方法?我不想通过将数据库中使用的方法拖入其中来使域模型复杂化,这不应该影响模型。

备注:

最初,在读取数据库之前,我认为模型中的参数应该由一组属性表示,例如:

    // Bike model
public class BikeModel {
    public BikeModel(string name, double height, double width) {
        ChangeName(name);
        ChangeHeight(height);
        ChangeWidth(width);
    }


    // Bike model name
    public string Name { get; private set; }

    // Bike height 
    public double Height { get; private set; }

    // Bike width 
    public double Width { get; private }


    public void ChangeName(string name) {
        Name = name;
    }

    public void ChangeHeight(double height) {
        Height = height;
    }

    public void ChangeWidth(double width) {
        Width = width;
    }
}    

然而,在熟悉数据库之后,我意识到“参数”值隐藏了“情境”部分中提供的许多特征。事实证明,该参数可以由Generic类表示。

public class ParameterOfModel<T> {
    public ParameterOfModel(string name, T value, string units) {
        SetName(name);
        SetValue(value);
        SetUnits(units);
    }

    // Parameter name
    public string Name { get; private set; }

    // Parameter value
    public T Value { get; private set; }

    // Units of the parameter
    public string Units { get; private set; }


    public void SetName(string name) {
        Name = name;
    }

    public void SetValue(T value) {
        Value = value;
    }

    public void SetUnits(string units) {
        Units = units;
    }
}

在这种情况下,Bike模型将采用以下形式:

    // Bike model class
public class BikeModel {
    public BikeModel(string name, double height, double width) {
        ChangeName(name);
        ChangeHeight(height);
        ChangeWidth(width);

        AdditionalNumericParams = new List<ParameterOfModel<double>>();
    }


    // Bike model name
    public string Name { get; private set; }

    // Bike height
    public ParameterOfModel<double> Height { get; private set; }

    // Bike width 
    public ParameterOfModel<double> Width { get; private set; }

    // Additional numeric parameters
    public List<ParameterOfModel<double>> AdditionalNumericParams { get; private set; }


    public void ChangeName(string name) {
        Name = name;
    }

    public void ChangeHeight(double height) {
        Height = new ParameterOfModel<double>("Bike height", height, "Centimeters");
    }

    public void ChangeWidth(double width) {
        Width = new ParameterOfModel<double>("Bike height", width, "Centimeters");
    }

    // Add an additional parameter to the model
    public void AddNewNumericParam(ParameterOfModel<double> additionalParameter) {
        AdditionalNumericParams.Add(additionalParameter);
    }
}

但是如何使用查找表编译这样的参数?

1 个答案:

答案 0 :(得分:0)

你可以做到。只需在聚合中使用存储库模式即可。 请检查以下内容以从db模型转换为您的域模型

public static BikeModel ConvertToModel(BikeTable dbTable)
{
    var bikeModel =
        new BikeModel(dbTable.Name, dbTable.Height, dbTable.Width);

    if (dbTable.AdditionalProps != null)
    {
        bikeModel.AddNewNumericParam(dbTable.AdditionalNumericParams);
    }

    return tenantEntity;
}

然后你可以这个列表

private static IEnumerable<BikeModel> ConvertToModel(IEnumerable<BikeTable> enumerable)
{
    return enumerable.Select(ConvertToModel);
}

public async Task<IEnumerable<TenantEntity>> Find(string term)
{    
    var lst = await _bikeRepository.GetAllAsync();

    return ConvertToModel(lst);
}

您可以添加扩展方法以提高可读性。

但是,我认为您设计应用程序的方式几乎没有问题。当你试图实现不变性时,我看不出使用私有集的任何价值。您可以通过添加where T: struct来限制T,看起来您将主要使用原始数据类型,因此struct可以是一个很好的候选者