Skip to content

Instantly share code, notes, and snippets.

@vmysla
Last active December 15, 2015 20:09
Show Gist options
  • Save vmysla/5316941 to your computer and use it in GitHub Desktop.
Save vmysla/5316941 to your computer and use it in GitHub Desktop.
// Subject: Complex object with set of properties and inner objectss
// Mission: Describe fluent DSL to define scheme and delegate action execution
//
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Text.RegularExpressions;
namespace ConsoleApplication1
{
internal class Program
{
// Scheme:
public class Group
{
public string Name;
}
private class User
{
public string Profile { get; set; }
public Group Group;
}
// DSL:
public class Cascade<T> where T:class ,new ()
{
private T Entity;
protected List<Func<object>> References = new List<Func<object>>();
public Cascade(T entity) { Entity = entity; }
public Cascade(T entity, List<Func< object>> references)
{
Entity = entity;
References = references;
}
public Cascade<T> Reference(Expression<Func<T, object>> expression)
{
RegisterReference(expression);
return this;
}
public Cascade<TEntity> Depended<TEntity>(Expression<Func<T, TEntity>> expression) where TEntity : class, new()
{
TEntity depended = RegisterReference(expression)(Entity);
return new Cascade<TEntity>(depended, References);
}
public void Execute(string action)
{
foreach (Func<object> reference in References)
{
var value = reference();
Console.WriteLine("Executed {0} for {1}",action, value);
}
}
public Func<T, TResult> RegisterReference<TResult>(Expression<Func<T, TResult>> expression) where TResult : class, new ()
{
Func<T, TResult> func = expression.Compile();
References.Add(() => func(Entity) );
Debug("Registered", expression);
return func;
}
// Action delegate:
private static void Debug<TResult>(string action, Expression<Func<T, TResult>> expression)
{
Console.WriteLine("{0} {1}", action, MemberExpressionName(expression));
}
private static string MemberExpressionName<TResult>(Expression<Func<T, TResult>> expression)
{
MemberExpression memberExpression = expression.Body as MemberExpression;
return memberExpression.Member.Name;
}
}
// Usage:
private static void Main(string[] args)
{
User user = new User();
user.Profile = "admin";
user.Group = new Group();
user.Group.Name = "users";
Cascade<User> userCascade
= new Cascade<User>(user);
userCascade
.Reference(u => u.Profile)
.Depended(u => u.Group)
.Reference(group => group.Name);
userCascade.Execute("delete");
Console.ReadLine();
return;
}
}
}
@vmysla
Copy link
Author

vmysla commented Apr 5, 2013

Output:
Registered Profile
Registered Group
Registered Name
Executed delete for admin
Executed delete for ConsoleApplication1.Program+Group
Executed delete for users

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment