Last active
December 15, 2015 20:09
-
-
Save vmysla/5316941 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Output:
Registered Profile
Registered Group
Registered Name
Executed delete for admin
Executed delete for ConsoleApplication1.Program+Group
Executed delete for users