是否可以在域模型上创建不可变属性?

时间:2016-08-29 12:26:30

标签: vb.net automapper dapper

我们有许多逻辑域对象都位于同一物理数据库表WorkStep中。 sql表中元数据的简单示例是 ID |NAME| TYPETYPE是定义可能类型的表的FK。但是,一旦从数据库中选择,每行可能代表不同的域模型,必须应用非常不同的业务规则。我现在正在使用的业务规则是,一旦创建了WorkStepType属性,其中一个对象就可以从不更改。所以,任何对此的调用都会导致改变这将是一件非常糟糕的事情。

那么,是否可以创建一个可以通过诸如automapper和dapper之类的附加组件构建的对象,它可以设置一次属性。从未改变过?而且,类型不能相互铸造。

我没有尝试太多,我甚至不确定没有hacky代码可以做到这一点

2 个答案:

答案 0 :(得分:1)

Dapper映射到私有属性(或私有setter / mutators)。

public class WorkStep
{
    public WorkStepType WorkStepType { get; private set;}
}

如果您需要将生成的域对象作为特定类型,那么只需将上面的类设置为生成您要查找的类型的简单工厂。

public class WorkStepFactory
    {
        public WorkStepType WorkStepType { get; private set;}

public T CreateWorkStep<T>() where T : WorkStepBase{...} 
    }

答案 1 :(得分:0)

我认为这是两个独立的操作。

第一个是返回可用WorkStepType个对象的列表,第二个是将它作为不可变属性分配给“workflow”类,为不同对象公开泛型类型。

注意 - 语法是C#6。不确定VB.NET的等价物是什么。

实施例

public class WorkStepType 
{
    // immutable properties
    public int Id { get; }
    public string Name { get; }

    public WorkStepType(int id, string name)
    {
        this.Id = id;
        this.Name = name;
    }
}

通用类为

public class Workflow<T>
{
    public WorkStepType WorkStep { get; }
    public T DomainModel { get; }

    public Workflow(WorkStepType type, T domainModel)
    {
        this.WorkStep = type;
        this.DomainModel = domainModel;
    }
}

您如何选择保湿这些物品取决于您。如果您使用Drapper(构建在Dapper之上),您可能会有一个类似于下面的存储库类(虽然我主张为WorkStepType / Workflows提供单独的CRUD存储库,这是为了说明这个想法)

public class WorkflowRepository
{
    // IDbCommander is a Drapper construct. 
    private readonly IDbCommander _commander;

    public WorkflowRepository(IDbCommander commander)
    {
        this._commander = commander;
    }

    public IEnumerable<WorkStepType> RetrieveAllWorkSteps()
    {
        // return all the available workstep types available 
        // to the user/application
        return _commander.Query<WorkStepType>();
    }

    public Workflow Retrieve(WorkStepType type)
    {
        // lookup the specific domain model for the supplied
        // workstep type. 
        var domainModel = _commander.Query<Workflow>(new { id = type.Id }).SingleOrDefault();
        return new Workflow(type, domainModel);
    }
}

这种方法应该为您提供您正在寻找的行为并证明其具有高度可测试性。

您可能希望公开设置域模型,具体取决于您是否要将新实例分配给现有WorkStepType。不确定你的设计/需求,但我相信你得到了要点。

希望有所帮助。