Ik heb geen idee of dit de goede term is maar ik zal uitleggen wat ik bedoel. Ik ben bezig met een mini workflow engine en ik wil conditions kunnen beheren. De flow zelf is altijd sequentueel. Per workflow kunnen er condities gekoppeld worden. De condities moeten vervolgens op run-time berekend worden.
Simpel voorbeeld:
--> Workflow 1
----- Gegevens worden opgehaald, bijvoorbeeld:
--> Workflow 2 (*Conditie voor volgende workflow: person.DateOfBirth.Year >= 1990)
--> Workflow 3 (*Geen condities)
De problemen waar ik tegen aanliep zijn de expressies binnen .NET zelf. Hier kan ik naar mijn idee geen gebruik van maken omdat ze altijd direct worden uitgevoerd. Er is geen manier om 1 + 1 == 2 op een later moment uit te voeren en deze expressie zal altijd direct een resultaat terug geven.
Toen kwam ik uit bij Linq en heb hier wel wat mooie dingen in kunnen bereiken:
Ik kan met deze code een expressie opbouwen en later uitvoeren. Nadeel is dat de code niet type-safe is en er altijd gecasted moet worden (mijn voorkeur gaat uit naar type-safe).
Met generics lukt me dit niet denk ik aangezien je altijd een T of X of whatever meegeeft. Je bepaald in je signature dan al hoeveel argumenten er meegegeven kunnen worden. Eigenlijk zoek ik een soort van params functie voor generics alleen moeten de typen dan ook kunnen verschillen.
Wat ik zou kunnen doen is een aantal copies maken van de delegate en de CheckCondition<..>() functie in bovenstaande code, zodat je verschillende types mee kan sturen. Dit is wel een grote beperking omdat de hoeveelheid type-safe vergelijkingen je kan maken afhangt van de hoeveelheid T / U / V / W / X / Y / Z types je mee stuurt. Zijn hier mooie oplossingen voor zonder dat je 20 copies moet maken met verschillende generic types.
Ik hoop dat mijn verhaal een beetje duidelijk is
Simpel voorbeeld:
--> Workflow 1
----- Gegevens worden opgehaald, bijvoorbeeld:
code:
1
| Person p = new Person("Piet", new DateOfBirth(1970, 1, 1)); |
--> Workflow 2 (*Conditie voor volgende workflow: person.DateOfBirth.Year >= 1990)
--> Workflow 3 (*Geen condities)
De problemen waar ik tegen aanliep zijn de expressies binnen .NET zelf. Hier kan ik naar mijn idee geen gebruik van maken omdat ze altijd direct worden uitgevoerd. Er is geen manier om 1 + 1 == 2 op een later moment uit te voeren en deze expressie zal altijd direct een resultaat terug geven.
Toen kwam ik uit bij Linq en heb hier wel wat mooie dingen in kunnen bereiken:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
| #region Solution 1 delegate bool ConditionDelegate(object[] values); private void btnSolution1_Click(object sender, EventArgs e) { ConditionDelegate @delegate = x => Convert.ToInt32(x[0]) >= 0 && Convert.ToInt32(x[0]) <= 10 && ((Person) x[1]).DateOfBirth.Year <= 1980; Person person = new Person(); person.DateOfBirth = new DateTime(1990, 1, 1); bool result = CheckCondition(@delegate, 5, person); } private bool CheckCondition(ConditionDelegate @delegate, params object[] values) { return @delegate(values); } #endregion |
Ik kan met deze code een expressie opbouwen en later uitvoeren. Nadeel is dat de code niet type-safe is en er altijd gecasted moet worden (mijn voorkeur gaat uit naar type-safe).
Met generics lukt me dit niet denk ik aangezien je altijd een T of X of whatever meegeeft. Je bepaald in je signature dan al hoeveel argumenten er meegegeven kunnen worden. Eigenlijk zoek ik een soort van params functie voor generics alleen moeten de typen dan ook kunnen verschillen.
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
| #region Solution 2 delegate bool ConditionDelegate<T>(T value); private void btnSolution2_Click(object sender, EventArgs e) { ConditionDelegate<Person> @delegate = x => x.DateOfBirth.Year <= 1980; Person person = new Person(); person.DateOfBirth = new DateTime(1990, 1, 1); bool result = CheckCondition<Person>(@delegate, person); } private bool CheckCondition<T>(ConditionDelegate<T> @delegate, T value) { return @delegate(value); } #endregion |
Wat ik zou kunnen doen is een aantal copies maken van de delegate en de CheckCondition<..>() functie in bovenstaande code, zodat je verschillende types mee kan sturen. Dit is wel een grote beperking omdat de hoeveelheid type-safe vergelijkingen je kan maken afhangt van de hoeveelheid T / U / V / W / X / Y / Z types je mee stuurt. Zijn hier mooie oplossingen voor zonder dat je 20 copies moet maken met verschillende generic types.
Ik hoop dat mijn verhaal een beetje duidelijk is
PSN: Norfirin