Skip to content

Instantly share code, notes, and snippets.

@emiaj
Created April 25, 2011 21:33
Show Gist options
  • Select an option

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

Select an option

Save emiaj/941283 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 ISparkViewRenderer
{
void Render(SparkViewBase view);
void RenderAsPartial(SparkViewBase view);
}
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 class SparkViewRenderer : ISparkViewRenderer
{
private readonly PartialOutput _partialOutput;
private readonly IOutputWriter _outputWriter;
private readonly ISparkViewActivator _activator;
public SparkViewRenderer(PartialOutput partialOutput, IOutputWriter outputWriter, ISparkViewActivator activator)
{
_partialOutput = partialOutput;
_outputWriter = outputWriter;
_activator = activator;
}
public void Render(SparkViewBase view)
{
var writer = new StringWriter();
_activator.Activate(view);
_partialOutput.SetWriter(() => view.Output);
view.Output = writer;
view.RenderView(writer);
_outputWriter.WriteHtml(writer);
}
public void RenderAsPartial(SparkViewBase view)
{
_activator.Activate(view);
view.RenderView(_partialOutput.Writer);
}
}
public interface ISparkViewAdapter
{
SparkViewBase GetView(ISparkViewEngine engine);
SparkViewBase GetPartialView(ISparkViewEngine engine);
}
public class SparkViewAdapter : ISparkViewAdapter
{
private readonly Func<ISparkViewEngine, ISparkView> _view;
private readonly Func<ISparkViewEngine, ISparkView> _partialView;
public SparkViewAdapter(Func<ISparkViewEngine, ISparkView> view, Func<ISparkViewEngine, ISparkView> partialView)
{
_view = view;
_partialView = partialView;
}
public SparkViewBase GetView(ISparkViewEngine engine)
{
return (SparkViewBase)_view(engine);
}
public SparkViewBase GetPartialView(ISparkViewEngine engine)
{
return (SparkViewBase)_partialView(engine);
}
}
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 adapter = new SparkViewAdapter(view, partialView);
def.DependencyByValue(typeof (ISparkViewAdapter), adapter);
}
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 ISparkViewAdapter _viewAdapter;
private readonly ISparkViewRenderer _renderer;
private readonly RenderContext _renderContext;
private readonly ISparkViewEngine _engine;
public RenderSparkViewBehavior(ISparkViewAdapter viewAdapter, RenderContext renderContext, ISparkViewEngine engine, ISparkViewRenderer renderer)
: base(PartialBehavior.Executes)
{
_viewAdapter = viewAdapter;
_renderer = renderer;
_renderContext = renderContext;
_engine = engine;
}
protected override DoNext performInvoke()
{
if(!_renderContext.IsPartial())
{
_renderContext.SetAsPartial();
_renderer.Render(_viewAdapter.GetView(_engine));
}
else
{
_renderer.RenderAsPartial(_viewAdapter.GetPartialView(_engine));
}
return DoNext.Continue;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment