Skip to content

Instantly share code, notes, and snippets.

@emiaj
Created February 14, 2011 19:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save emiaj/826358 to your computer and use it in GitHub Desktop.
Save emiaj/826358 to your computer and use it in GitHub Desktop.
// Theme
public interface ITheme
{
void AddElement(IThemeElement element);
IEnumerable<IThemeElement> Elements { get; }
}
public class Theme : ITheme
{
private readonly IList<IThemeElement> _elements;
public Theme()
{
_elements = new List<IThemeElement>();
}
public void AddElement(IThemeElement element)
{
_elements.Add(element);
}
public IEnumerable<IThemeElement> Elements
{
get { return _elements; }
}
}
// Theme Elements
public interface IThemeElement
{
TextWriter Writer { get; }
}
public class Skin : IThemeElement
{
private readonly Func<TextWriter> _writerSource;
public Skin(Func<TextWriter> writerSource)
{
_writerSource = writerSource;
}
public TextWriter Writer { get { return _writerSource(); } }
}
public class Layout:IThemeElement
{
private readonly Func<TextWriter> _writerSource;
public Layout(string name, Func<TextWriter> writerSource)
{
Name = name;
_writerSource = writerSource;
}
public string Name { get; private set; }
public TextWriter Writer { get { return _writerSource(); } }
}
public class Zone : IThemeElement
{
private readonly Func<TextWriter> _writerSource;
public Zone(string name, Func<TextWriter> writerSource)
{
_writerSource = writerSource;
Name = name;
}
public string Name { get; private set; }
public TextWriter Writer { get { return _writerSource(); } }
}
public class Container : IThemeElement
{
private readonly Func<TextWriter> _writerSource;
public Container(string name, string zone, Func<TextWriter> writerSource)
{
_writerSource = writerSource;
Name = name;
Zone = zone;
}
public string Name { get; private set; }
public string Zone { get; private set; }
public TextWriter Writer { get { return _writerSource(); } }
}
public class Engine : IThemeElement
{
private readonly Func<TextWriter> _writerSource;
public Engine(Action action, Func<TextWriter> writerSource)
{
_writerSource = writerSource;
Action = action;
}
public Action Action { get; private set; }
public TextWriter Writer { get { return _writerSource(); } }
}
// Theme Composition
public interface IThemeComposition
{
ITheme Compose();
}
public class ThemeComposition : IThemeComposition
{
private readonly IEnumerable<IElementComposer> _composers;
private readonly ICompositionContext _context;
public ThemeComposition(IEnumerable<IElementComposer> composers,ICompositionContext context)
{
_composers = composers;
_context = context;
}
public ITheme Compose()
{
var theme = new Theme();
_composers.SelectMany(x => x.Compose(_context))
.Each(theme.AddElement);
return theme;
}
}
// Element Composers
public interface IElementComposer
{
IEnumerable<IThemeElement> Compose(ICompositionContext context);
}
public abstract class SingleElementComposer : IElementComposer
{
public IEnumerable<IThemeElement> Compose(ICompositionContext context)
{
return new[] {Single(context)};
}
protected abstract IThemeElement Single(ICompositionContext context);
}
public class SkinElementComposer:SingleElementComposer
{
protected override IThemeElement Single(ICompositionContext context)
{
return new Skin(() => context.OutputScope.Create(context.Page.Skin));
}
}
public class LayoutElementComposer : SingleElementComposer
{
protected override IThemeElement Single(ICompositionContext context)
{
return new Layout(context.Page.Layout, () => context.OutputScope.Create(context.Page.Layout));
}
}
public class ZoneElementComposer:IElementComposer
{
private readonly ISkinService _skinService;
public ZoneElementComposer(ISkinService skinService)
{
_skinService = skinService;
}
public IEnumerable<IThemeElement> Compose(ICompositionContext context)
{
var zones = _skinService.GetSkin(context.Page.Skin)
.Layouts.First(x => x.Name == context.Page.Layout)
.Zones;
foreach (var zone in zones)
{
var local = zone;
yield return new Zone(local.Name, () => context.OutputScope.Create(local.Name));
}
}
}
public class ContainerElementComposer:IElementComposer
{
public IEnumerable<IThemeElement> Compose(ICompositionContext context)
{
foreach (var renderInfo in context.Page.Slices.Select(x=>x.RenderInfo))
{
var local = renderInfo;
Func<TextWriter> writerSource = () => context.OutputScope.Create(local.Zone + "_content");
var container = new Container(local.Container, local.Zone,writerSource);
yield return container;
}
}
}
public class EngineElementComposer:IElementComposer
{
private readonly IEnumerable<IEngineInvocation> _invocations;
public EngineElementComposer(IEnumerable<IEngineInvocation> invocations)
{
_invocations = invocations;
}
public IEnumerable<IThemeElement> Compose(ICompositionContext context)
{
foreach (var invocation in _invocations)
{
var local = invocation;
var slice = local.Metadata<Slice>();
var engine = new Engine(local.Invoke, () => context.OutputScope.Create(slice.RenderInfo.Container));
yield return engine;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment