Created
February 14, 2011 19:01
-
-
Save emiaj/826358 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
// 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