I’ve seen several try to do DCI in C# but with the usual drawbacks from languages that are inherently class oriented. However Microsoft has a project Called Roslyn which is currently a CTP but I decided to try it out to see if I could use that to do tricks similar to what I’ve done with maroon.
It turned out to be very easy to work with and within a few hours I was able to translate my first DCI program written fully in C#. The trick as with maroon (and essentially Marvin as well) is that I rewrite the code before it get’s compiled.
A context class is declared as a regular class but with the Context attribute
A role is declared as an inner class with a role attribute and can be used as a variable.
The MoneyTransfer might then look like this
[Context] public class MoneyTransfer<TSource, TDestination> where TSource : ICollection<LedgerEntry> where TDestination : ICollection<LedgerEntry> { public MoneyTransfer(Account<TSource> source, Account<TDestination> destination, decimal amount) { Source = source; Destination = destination; Amount = amount; } [Role] private class Source : Account<TSource> { void Withdraw(decimal amount) { this.DecreaseBalance(amount); } void Transfer(decimal amount) { Console.WriteLine("Source balance is: " + this.Balance); Console.WriteLine("Destination balance is: " + Destination.Balance); Destination.Deposit(amount); this.Withdraw(amount); Console.WriteLine("Source balance is now: " + this.Balance); Console.WriteLine("Destination balance is now: " + Destination.Balance); } } [Role] private class Destination : Account<TDestination> { void Deposit(decimal amount) { this.IncreaseBalance(amount); } } [Role] public class Amount { } public void Trans() { Source.Transfer(Amount); } }
If a base class is declared for the inner classes then these will be used as the type of the role field, if no base class is provided then the field will be declared dynamic. The source for Interact as the tool is called can be found at github
Roslyn made this very easy and I plan to see if I can make Interact feature complete compared to Marvin. The syntax will not be as fluid because I can’t change the grammar but the upside will be a more stable solution with the same or less effort.
[…] Pure DCI in C# […]