Skip to content

Commit

Permalink
Using the Microsoft.Extensions.DependencyInjection apis to resolved d…
Browse files Browse the repository at this point in the history
…ependencies

- Now using constructor injection instead of auto-initializing properties
- Removed ISparkServiceInitialize and ISparkServiceContainer (and it's implementation)
- New IBatchCompiler interface so that we can use different compilers
- ~2x performance improvement when compiling views with Roslyn
- CodeDom compilation can still be used at the moment (class marked as obsolete)
- CastleMonoRail still using codedom (rosylin doesn't like the assembly name when compiling in that project)
  • Loading branch information
bounav committed Jan 24, 2024
1 parent 51bce7f commit 7de6466
Show file tree
Hide file tree
Showing 84 changed files with 2,005 additions and 1,879 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,12 @@ public class SparkBatchCompilerTester
[SetUp]
public void Init()
{
var settings = new SparkSettings();
var settings = new SparkSettings()
.SetPageBaseType(typeof(SparkView));

var services = new StubMonoRailServices();
services.AddService(typeof(ISparkSettings), settings);
services.AddService(typeof(IViewSourceLoader), new FileAssemblyViewSourceLoader("MonoRail.Tests.Views"));
services.AddService(typeof(ISparkViewEngine), new SparkViewEngine(settings));
services.AddService(typeof(IControllerDescriptorProvider), services.ControllerDescriptorProvider);
_factory = new SparkViewFactory();
_factory.Service(services);
Expand All @@ -59,7 +60,7 @@ public void CompileBatchDescriptor()
var assembly = _factory.Precompile(batch);

Assert.IsNotNull(assembly);
Assert.AreEqual(3, assembly.GetTypes().Length);
Assert.AreEqual(3, assembly.GetTypes().Count(x => x.BaseType == typeof(SparkView)));
}

[Test]
Expand Down Expand Up @@ -98,7 +99,7 @@ public void MultipleLayoutFiles()
var assembly = _factory.Precompile(batch);

Assert.IsNotNull(assembly);
Assert.AreEqual(4, assembly.GetTypes().Length);
Assert.AreEqual(4, assembly.GetTypes().Count(x => x.BaseType == typeof(SparkView)));
}

[Test]
Expand Down Expand Up @@ -131,7 +132,7 @@ public void WildcardIncludeRules()
var assembly = _factory.Precompile(batch);

Assert.IsNotNull(assembly);
Assert.AreEqual(3, assembly.GetTypes().Length);
Assert.AreEqual(3, assembly.GetTypes().Count(x => x.BaseType == typeof(SparkView)));
}

[Test]
Expand Down
4 changes: 2 additions & 2 deletions src/Castle.MonoRail.Views.Spark.Tests/SparkViewDataTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ public void PropertyBagAvailable()
controllerContext.PropertyBag.Add("foo", "bar");

mocks.ReplayAll();
view.Contextualize(engineContext, controllerContext, null, null);
view.Contextualize(engineContext, controllerContext, null, null, null);

Assert.AreEqual("bar", view.ViewData["foo"]);
}
Expand All @@ -71,7 +71,7 @@ public void MergingCollectionsLikeVelocity()
engineContext.Request.Params.Add("contextParamsKey", "contextParamsValue");
controllerContext.Resources.Add("controllerResourcesKey", resource);

view.Contextualize(engineContext, controllerContext, null, null);
view.Contextualize(engineContext, controllerContext, null, null, null);

Assert.AreEqual("controllerPropertyBagValue", view.ViewData["controllerPropertyBagKey"]);
Assert.AreEqual("contextFlashValue", view.ViewData["contextFlashKey"]);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,13 @@ public class SparkViewFactoryStrictNullBehaviourTests : SparkViewFactoryTestsBas
{
protected override void Configure()
{
var settings = new SparkSettings();
var settings =
new SparkSettings()
.SetPageBaseType(typeof(SparkView));

settings.SetNullBehaviour(NullBehaviour.Strict);
var sparkViewEngine = new SparkViewEngine(settings);
serviceProvider.AddService(typeof(ISparkViewEngine), sparkViewEngine);

serviceProvider.AddService(typeof(ISparkSettings), settings);

factory = new SparkViewFactory();
factory.Service(serviceProvider);
Expand Down
50 changes: 27 additions & 23 deletions src/Castle.MonoRail.Views.Spark.Tests/SparkViewFactoryTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,21 +27,25 @@ namespace Castle.MonoRail.Views.Spark.Tests

[TestFixture]
public class SparkViewFactoryTests : SparkViewFactoryTestsBase
{
protected override void Configure()
{
factory = new SparkViewFactory();
factory.Service(serviceProvider);

manager = new DefaultViewEngineManager();
manager.Service(serviceProvider);
serviceProvider.ViewEngineManager = manager;
serviceProvider.AddService(typeof(IViewEngineManager), manager);
serviceProvider.AddService(typeof(ISparkSettings), new SparkSettings());
{
protected override void Configure()
{
var settings = new SparkSettings()
.SetPageBaseType(typeof(SparkView));

serviceProvider.AddService(typeof(ISparkSettings), settings);

factory = new SparkViewFactory();
factory.Service(serviceProvider);

manager.RegisterEngineForExtesionLookup(factory);
manager.RegisterEngineForView(factory);
}
manager = new DefaultViewEngineManager();
manager.Service(serviceProvider);
serviceProvider.ViewEngineManager = manager;
serviceProvider.AddService(typeof(IViewEngineManager), manager);

manager.RegisterEngineForExtesionLookup(factory);
manager.RegisterEngineForView(factory);
}

[Test]
public void ExtensionIsSpark()
Expand Down Expand Up @@ -69,7 +73,7 @@ public void ContextAndControllerContextAvailable()
descriptor.Templates.Add(string.Format("Shared{0}default.spark", Path.DirectorySeparatorChar));
var entry = factory.Engine.GetEntry(descriptor);
var view = (SparkView)entry.CreateInstance();
view.Contextualize(engineContext, controllerContext, factory, null);
view.Contextualize(engineContext, controllerContext, serviceProvider.GetService<IResourcePathManager>(), factory, null);

var result = new StringWriter();
view.RenderView(result);
Expand Down Expand Up @@ -114,14 +118,14 @@ public void NullBehaviourConfiguredToLenient()
{
mocks.ReplayAll();
manager.Process(string.Format("Home{0}NullBehaviourConfiguredToLenient", Path.DirectorySeparatorChar), output, engineContext, controller, controllerContext);
var content = output.ToString();
Assert.IsFalse(content.Contains("default"));

ContainsInOrder(content,
"<p>name kaboom *${user.Name}*</p>",
"<p>name silently **</p>",
"<p>name fixed *fred*</p>");
}
var content = output.ToString();
Assert.IsFalse(content.Contains("default"));

ContainsInOrder(content,
"<p>name kaboom *${user.Name}*</p>",
"<p>name silently **</p>",
"<p>name fixed *fred*</p>");
}

[Test]
public void TerseHtmlEncode()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,7 @@ public class BaseViewComponentTests
protected StubEngineContext engineContext;
protected SparkViewFactory factory;
protected IController controller;
protected SparkViewEngine engine;


[SetUp]
public virtual void Init()
{
Expand All @@ -45,9 +44,11 @@ public virtual void Init()
services.AddService(typeof(IViewComponentFactory), viewComponentFactory);
services.AddService(typeof(IViewComponentRegistry), viewComponentFactory.Registry);

var settings = new SparkSettings();
engine = new SparkViewEngine(settings);
services.AddService(typeof(ISparkViewEngine), engine);
var settings = new SparkSettings()
.SetPageBaseType(typeof(SparkView));
services.AddService(typeof(ISparkSettings), settings);

services.AddService(typeof(IResourcePathManager), new DefaultResourcePathManager(settings));

factory = new SparkViewFactory();
factory.Service(services);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
using System.Reflection;
using Castle.MonoRail.Framework;
using NUnit.Framework;
using Spark;
using Spark.FileSystem;

namespace Castle.MonoRail.Views.Spark.Tests.ViewComponents
Expand Down Expand Up @@ -81,7 +82,7 @@ public void ComponentRenderViewFromEmbeddedResource()
Assembly.Load("Castle.MonoRail.Views.Spark.Tests"),
"Castle.MonoRail.Views.Spark.Tests.EmbeddedViews");

engine.ViewFolder = engine.ViewFolder.Append(embeddedViewFolder);
this.factory.Engine.ViewFolder = this.factory.Engine.ViewFolder.Append(embeddedViewFolder);

mocks.ReplayAll();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,11 +77,12 @@ public override void Install(IDictionary stateSaver)
// Attempt to get the configuration from settings, otherwise use default settings
var settings =
(ISparkSettings)config.GetSection("spark") ??
new SparkSettings();
new SparkSettings()
.SetPageBaseType(typeof(SparkView));

var services = new StubMonoRailServices();
services.AddService(typeof(ISparkSettings), settings);
services.AddService(typeof(IViewSourceLoader), new FileAssemblyViewSourceLoader(viewsLocation));
services.AddService(typeof(ISparkViewEngine), new SparkViewEngine(settings));
services.AddService(typeof(IControllerDescriptorProvider), services.ControllerDescriptorProvider);

var factory = new SparkViewFactory();
Expand Down
8 changes: 5 additions & 3 deletions src/Castle.MonoRail.Views.Spark/SparkView.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ protected SparkView()

private IEngineContext _context;
private IControllerContext _controllerContext;
private IResourcePathManager _resourcePathManager;
private SparkViewFactory _viewEngine;
private IDictionary _contextVars;

Expand All @@ -54,7 +55,7 @@ protected SparkView()
public string SiteRoot { get { return _context.ApplicationPath; } }
public string SiteResource(string path)
{
return _viewEngine.Engine.ResourcePathManager.GetResourcePath(SiteRoot, path);
return this._resourcePathManager.GetResourcePath(SiteRoot, path);
}

public IDictionary PropertyBag { get { return _contextVars ?? _controllerContext.PropertyBag; } }
Expand Down Expand Up @@ -91,10 +92,11 @@ public string Eval(string expression, string format)
public T Helper<T>() where T : class { return ControllerContext.Helpers[typeof(T).Name] as T; }
public T Helper<T>(string name) where T : class { return ControllerContext.Helpers[name] as T; }

public virtual void Contextualize(IEngineContext context, IControllerContext controllerContext, SparkViewFactory viewEngine, SparkView outerView)
public virtual void Contextualize(IEngineContext context, IControllerContext controllerContext, IResourcePathManager resourcePathManager, SparkViewFactory viewEngine, SparkView outerView)
{
_context = context;
_controllerContext = controllerContext;
_resourcePathManager = resourcePathManager;
_viewEngine = viewEngine;

if (_viewEngine != null && _viewEngine.CacheServiceProvider != null)
Expand Down Expand Up @@ -132,7 +134,7 @@ public void RenderComponent(
var service = (IViewComponentFactory)_context.GetService(typeof(IViewComponentFactory));
var component = service.Create(name);

IViewComponentContext viewComponentContext = new ViewComponentContext(this, _viewEngine, name, parameters, body, sections);
IViewComponentContext viewComponentContext = new ViewComponentContext(this, _resourcePathManager, _viewEngine, name, parameters, body, sections);

var oldContextVars = _contextVars;
try
Expand Down
55 changes: 34 additions & 21 deletions src/Castle.MonoRail.Views.Spark/SparkViewFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,12 @@
using Castle.MonoRail.Framework.Resources;
using Castle.MonoRail.Framework.Routing;
using Castle.MonoRail.Views.Spark.Wrappers;
using Spark.Bindings;
using Spark.Compiler;
using Spark.Compiler.CodeDom;
using Spark.Compiler.Roslyn;
using Spark.Parser;
using Spark.Parser.Syntax;

namespace Castle.MonoRail.Views.Spark
{
Expand All @@ -36,16 +41,18 @@ public class SparkViewFactory : ViewEngineBase, IViewSourceLoaderContainer
{
private IControllerDescriptorProvider _controllerDescriptorProvider;
private IViewActivatorFactory _viewActivatorFactory;
private IResourcePathManager _resourcePathManager;

public override void Service(IServiceProvider provider)
{
base.Service(provider);

_controllerDescriptorProvider = (IControllerDescriptorProvider)provider.GetService(typeof(IControllerDescriptorProvider));
_viewActivatorFactory = (IViewActivatorFactory)provider.GetService(typeof(IViewActivatorFactory));
_resourcePathManager = (IResourcePathManager)provider.GetService(typeof(IResourcePathManager));
_cacheServiceProvider = (ICacheServiceProvider)provider.GetService(typeof(ICacheServiceProvider));

SetEngine((ISparkViewEngine)provider.GetService(typeof(ISparkViewEngine)));
Engine = (ISparkViewEngine)provider.GetService(typeof(ISparkViewEngine));
}

private ISparkViewEngine _engine;
Expand All @@ -55,29 +62,35 @@ public ISparkViewEngine Engine
{
if (_engine == null)
{
SetEngine(new SparkViewEngine(new SparkSettings()));
var settings =
(ISparkSettings)this.serviceProvider.GetService(typeof(ISparkSettings))
?? new SparkSettings()
.SetPageBaseType(typeof(SparkView));

var partialProvider = new DefaultPartialProvider();

var viewFolder = new ViewSourceLoaderWrapper(this);

var batchCompiler = new CodeDomBatchCompiler();

this._engine =
new SparkViewEngine(
settings,
new DefaultSyntaxProvider(settings),
this._viewActivatorFactory ?? new DefaultViewActivator(),
new DefaultLanguageFactory(batchCompiler),
new CompiledViewHolder(),
viewFolder,
batchCompiler,
partialProvider,
new DefaultPartialReferenceProvider(partialProvider),
new DefaultBindingProvider(),
new ViewComponentExtensionFactory(this.serviceProvider));
}

return _engine;
}
set
{
SetEngine(value);
}
}

private void SetEngine(ISparkViewEngine engine)
{
_engine = engine;
if (_engine == null)
return;

_engine.ViewFolder = new ViewSourceLoaderWrapper(this);
_engine.ExtensionFactory = new ViewComponentExtensionFactory(serviceProvider);
_engine.DefaultPageBaseType = typeof(SparkView).FullName;

if (_viewActivatorFactory != null)
_engine.ViewActivatorFactory = _viewActivatorFactory;
set => this._engine = value;
}

private ICacheServiceProvider _cacheServiceProvider;
Expand Down Expand Up @@ -156,7 +169,7 @@ public override void Process(string templateName, TextWriter output, IEngineCont

var entry = Engine.CreateEntry(descriptor);
var view = (SparkView)entry.CreateInstance();
view.Contextualize(context, controllerContext, this, null);
view.Contextualize(context, controllerContext, _resourcePathManager, this, null);
if (view.Logger == null || view.Logger == NullLogger.Instance)
view.Logger = Logger;
view.RenderView(output);
Expand Down
7 changes: 4 additions & 3 deletions src/Castle.MonoRail.Views.Spark/ViewComponentContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,17 +26,18 @@ namespace Castle.MonoRail.Views.Spark
public class ViewComponentContext : IViewComponentContext
{
private readonly SparkView _view;
private readonly IResourcePathManager _resourcePathManager;
private readonly SparkViewFactory _viewEngine;
private readonly string _name;
private readonly IDictionary _componentParameters;
private readonly Action _body;
private readonly IDictionary<string, Action> _sections;
private readonly IDictionary _contextVarsAdapter;


public ViewComponentContext(SparkView view, SparkViewFactory viewEngine, string name, IDictionary componentParameters, Action body, IDictionary<string, Action> sections)
public ViewComponentContext(SparkView view, IResourcePathManager resourcePathManager, SparkViewFactory viewEngine, string name, IDictionary componentParameters, Action body, IDictionary<string, Action> sections)
{
_view = view;
_resourcePathManager = resourcePathManager;
_viewEngine = viewEngine;
_name = name;
_componentParameters = componentParameters;
Expand Down Expand Up @@ -68,7 +69,7 @@ public void RenderView(string name, TextWriter writer)

try
{
componentView.Contextualize(_view.Context, _view.ControllerContext, _viewEngine, _view);
componentView.Contextualize(_view.Context, _view.ControllerContext, _resourcePathManager, _viewEngine, _view);
componentView.RenderView(writer);
}
finally
Expand Down
Loading

0 comments on commit 7de6466

Please sign in to comment.