Skip to content

Instantly share code, notes, and snippets.

@emiaj
Created April 25, 2011 22:14
Show Gist options
  • Select an option

  • Save emiaj/941366 to your computer and use it in GitHub Desktop.

Select an option

Save emiaj/941366 to your computer and use it in GitHub Desktop.
public class RenderContext
{
private bool _isPartial;
public void SetAsPartial()
{
_isPartial = true;
}
public bool IsPartial()
{
return _isPartial;
}
}
public class PartialOutput
{
private Func<TextWriter> _writer;
public void SetWriter(Func<TextWriter> writer)
{
_writer = writer;
}
public TextWriter Writer
{
get
{
return _writer();
}
}
}
public interface ISparkViewActivator
{
void Activate(ISparkView sparkView);
}
public class SparkViewActivator : ISparkViewActivator
{
private readonly IServiceLocator _locator;
private readonly IFubuRequest _request;
public SparkViewActivator(IServiceLocator locator, IFubuRequest request)
{
_locator = locator;
_request = request;
}
public void Activate(ISparkView sparkView)
{
if (sparkView is IFubuPage)
{
((IFubuPage)sparkView).ServiceLocator = _locator;
}
if (sparkView is IFubuViewWithModel)
{
((IFubuViewWithModel)sparkView).SetModel(_request);
}
}
}
public interface IPartialRenderAction
{
void Execute();
}
public class PartialRenderAction : IPartialRenderAction
{
private readonly ISparkViewEngine _engine;
private readonly Func<ISparkViewEngine, ISparkView> _view;
private readonly PartialOutput _partialOutput;
private readonly ISparkViewActivator _activator;
public PartialRenderAction(ISparkViewEngine engine, Func<ISparkViewEngine, ISparkView> view, PartialOutput partialOutput, ISparkViewActivator activator)
{
_engine = engine;
_view = view;
_partialOutput = partialOutput;
_activator = activator;
}
public void Execute()
{
var view = _view(_engine);
_activator.Activate(view);
view.RenderView(_partialOutput.Writer);
}
}
public interface IRenderAction
{
void Execute();
}
public class RenderAction : IRenderAction
{
private readonly ISparkViewEngine _engine;
private readonly Func<ISparkViewEngine, ISparkView> _view;
private readonly ISparkViewActivator _activator;
private readonly PartialOutput _partialOutput;
private readonly IOutputWriter _outputWriter;
public RenderAction(ISparkViewEngine engine, Func<ISparkViewEngine, ISparkView> view, ISparkViewActivator activator, PartialOutput partialOutput, IOutputWriter outputWriter)
{
_engine = engine;
_outputWriter = outputWriter;
_partialOutput = partialOutput;
_activator = activator;
_view = view;
}
public void Execute()
{
var writer = new StringWriter();
var view = (SparkViewBase)_view(_engine);
view.Output = writer;
_activator.Activate(view);
_partialOutput.SetWriter(() => view.Output);
view.RenderView(writer);
_outputWriter.WriteHtml(writer);
}
}
public interface ISparkViewRenderer
{
void Render();
}
public class SparkViewRenderer : ISparkViewRenderer
{
private readonly IPartialRenderAction _partialAction;
private readonly IRenderAction _renderAction;
private readonly RenderContext _renderContext;
public SparkViewRenderer(IPartialRenderAction partialAction, IRenderAction renderAction, RenderContext renderContext)
{
_partialAction = partialAction;
_renderAction = renderAction;
_renderContext = renderContext;
}
public void Render()
{
if (_renderContext.IsPartial())
{
_partialAction.Execute();
}
else
{
_renderContext.SetAsPartial();
_renderAction.Execute();
}
}
}
public class SparkViewOutput : OutputNode<RenderSparkViewBehavior>
{
private static readonly IDictionary<int, ISparkViewEntry> _cache;
private readonly SparkItem _item;
static SparkViewOutput()
{
_cache = new Dictionary<int, ISparkViewEntry>();
}
public SparkViewOutput(SparkItem item) { _item = item; }
protected override void configureObject(ObjectDef def)
{
var descriptor = new SparkViewDescriptor();
var partialDescriptor = new SparkViewDescriptor();
descriptor.AddTemplate(_item.ViewPath);
if (_item.Master != null)
{
descriptor.AddTemplate(_item.Master.ViewPath);
}
partialDescriptor.AddTemplate(_item.ViewPath);
var descriptorKey = descriptor.GetHashCode();
var partialDescriptorKey = partialDescriptor.GetHashCode();
Func<ISparkViewEngine, ISparkView> view = engine => getView(engine, descriptor, descriptorKey);
Func<ISparkViewEngine, ISparkView> partialView = engine => getView(engine, partialDescriptor, partialDescriptorKey);
var renderer = def.DependencyByType(typeof (ISparkViewRenderer), typeof (SparkViewRenderer));
var normalAction = renderer.DependencyByType(typeof (IRenderAction), typeof (RenderAction));
var partialAction = renderer.DependencyByType(typeof (IPartialRenderAction), typeof (PartialRenderAction));
normalAction.DependencyByValue(view);
partialAction.DependencyByValue(partialView);
}
private static ISparkView getView(ISparkViewEngine engine, SparkViewDescriptor descriptor, int key)
{
ISparkViewEntry entry;
lock (_cache)
{
_cache.TryGetValue(key, out entry);
if (entry == null || !entry.IsCurrent())
{
entry = engine.CreateEntry(descriptor);
_cache[key] = entry;
}
}
return entry.CreateInstance();
}
public override string Description
{
get
{
return string.Format("Spark View [{0}]", _item.RelativePath());
}
}
}
public class RenderSparkViewBehavior : BasicBehavior
{
private readonly ISparkViewRenderer _renderer;
public RenderSparkViewBehavior(ISparkViewRenderer renderer)
: base(PartialBehavior.Executes)
{
_renderer = renderer;
}
protected override DoNext performInvoke()
{
_renderer.Render();
return DoNext.Continue;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment