Wir haben eine Anzahl von logischen WorkStep
, die sich alle in derselben physischen Datenbanktabelle WorkStep
. Ein einfaches Beispiel für die Metadaten in der SQL-Tabelle ist ID |NAME| TYPE
, so dass TYPE
ein FK für eine Tabelle ist, die die möglichen Typen definiert. Sobald sie jedoch aus der Datenbank ausgewählt wurde, repräsentiert jede Zeile möglicherweise ein anderes Domänenmodell mit sehr unterschiedlichen Geschäftsregeln, die angewendet werden müssen. Die Business - Regel arbeite ich mit jetzt ist , dass einmal erstellt, die WorkStepType
Eigenschaft eines dieser Objekte kann sie nie ändern. Also, jeder Anruf, der dazu führen würde, dass sich dies ändert, wäre eine sehr schlechte Sache.
So ist es möglich, ein Objekt zu erstellen, das über Add-Ons wie Automapper und Dapper erstellt werden kann, die eine Eigenschaft einmal festlegen können. und hat sich nie verändert? Außerdem können die Typen nicht miteinander umgewandelt werden.
Ich habe nicht viel versucht, ich bin mir nicht einmal sicher, ob es möglich ist, dies ohne Hacky-Code zu tun
Dapper passt auf private Eigenschaften (oder private Setter / Mutatoren).
public class WorkStep
{
public WorkStepType WorkStepType { get; private set;}
}
Wenn das resultierende Domänenobjekt ein bestimmter Typ sein soll, erstellen Sie einfach die obige Klasse als einfache Factory, die den gesuchten Typ generiert.
public class WorkStepFactory
{
public WorkStepType WorkStepType { get; private set;}
public T CreateWorkStep<T>() where T : WorkStepBase{...}
}
Ich sehe das als zwei getrennte Operationen.
Die erste wäre, eine Liste von verfügbaren WorkStepType
Objekten zurückzugeben, die zweite wäre, sie als unveränderbare Eigenschaft einer "Workflow" -Klasse zuzuordnen, die einen generischen Typ für Ihre verschiedenen Objekte WorkStepType
.
Hinweis - Syntax ist C # 6. Nicht sicher, was das VB.NET-Äquivalent wäre.
Beispiel
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;
}
}
Und die generische Klasse als
public class Workflow<T>
{
public WorkStepType WorkStep { get; }
public T DomainModel { get; }
public Workflow(WorkStepType type, T domainModel)
{
this.WorkStep = type;
this.DomainModel = domainModel;
}
}
Wie Sie diese Objekte hydratisieren können, bleibt Ihnen überlassen. Wenn Sie Drapper (auf Dapper) verwenden, haben Sie vielleicht eine Repository-Klasse, die ungefähr so aussieht (obwohl ich für WorkstpType / Workflows separate CRUD-Repositories befürworten würde, soll dies die Idee veranschaulichen)
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);
}
}
Dieser Ansatz sollte Ihnen das Verhalten geben, nach dem Sie suchen, und sich als sehr gut testbar erweisen.
Möglicherweise möchten Sie, dass das Domänenmodell in Abhängigkeit davon, ob Sie einem vorhandenen WorkStepType
eine neue Instanz zuweisen möchten, öffentlich einstellbar ist. Ich bin mir nicht sicher, ob Sie das Design / die Bedürfnisse haben, aber ich bin mir sicher, dass Sie das Wesentliche verstehen.
Ich hoffe, das hilft.