Using C# properties to create a domain specific language
So this is nothing new really. People have been creating DSLs using methods and properties for quite some while now I think. But I recently used it to make my fakes (in the unit tests) easier to understand. And I think it turned out pretty neat. Here is an example of what a fake could look like:
1: public class FakeDatabaseWithOneUser : IMyDatabase
2: {
3: List<User> _users = new List<User>();
4: List<Address> _addresses = new List<Address>();
5: List<Invoice> _invoices = new List<Invoice>();
6:
7: public FakeDatabase()
8: {
9: _users.Add(new User("First", "Name"));
10:
11: public FakeDatabase AndTwoAddresses
12: {
13: get
14: {
15: _addresses.Add(new Address("Delivery Address"));
16: _addresses.Add(new Address("Invoice Address"));
17: return this;
18: }
19: }
20:
21: public FakeDatabase AndOneInvoice
22: {
23: get
24: {
25: _invoices.Add(new Invoice());
26: return this;
27: }
28: }
29:
30: // IMyDatabase implementation not shown here.
31: }
And using that fake a unit test could look something like this:
1: [TestMethod]
2: public void SelectedUserShouldListAllAddresses()
3: {
4: IMyDatabase db = new FakeDatabaseWithOneUser().AndTwoAddresses;
5: Assert.AreEqual(2, db.SelectUser(1).Address.Count);
6: }
But why do I use properties and not methods? I know there are people who think this use of properties violates the semantics of a property since the getter changes the state of the object. I don't agree. First of all these are not properties, these are part of my DSL. Second I think getting rid of the parenthesis (which would be there if these were methods instead) is nice and makes the code look better.