Spark BuildProvider

29 views
Skip to first unread message

Asbjørn Ulsberg

unread,
Jun 2, 2010, 11:01:13 AM6/2/10
to Spark View Engine Dev
As the BatchCompiler in Spark is already doing most of the work
needed, why isn't there a SparkBuildProvider available for
registration with BuildProvider.RegisterBuildProvider(".spark",
typeof(SparkBuildProvider))?

I've made some attempts to build this myself, but I didn't get any
further than having my dynamically generated view code not compile
because the build manager didn't understand the "Spark" references
(yes, I did add Spark as referenced assemblies in the build provider).

The reason I need this is because I'm embedding the .spark views as
resources in the web project assembly to be able to load them in a
plug-in like system. I've tried the precompilation route, but as the
files would still need to exist physically on disk, I have to go
through my custom VirtualPathProvider and then just passing them on to
a build provider registered for the ".spark" extension would be so
much easier.

Any ideas on how to solve this? Would it be hard for Spark to expose a
proper BuildProvider to the outside world?

Asbjørn Ulsberg

unread,
Jun 4, 2010, 6:06:49 AM6/4/10
to Spark View Engine Dev
I still think Spark should have its own BuildProvider, but I've
managed to precompile the views instead. Now I'm facing problems with
having all of my views compiled, though. I started out with the
following:

Views
- Home
-- Index.spark

This compiled and all was swell. Then I added a master layout like so:

Views
- Home
-- Index.spark
- Shared
-- Site.spark

Now, only "Site.spark" is being compiled. My batch is described as
this:

e.Batch.For<HomeController>().Layout("Site").Include("Index");

Whatever I append to For<HomeController>(), "Index.spark" won't be
compiled. I've checked the resulting assembly in .NET Reflector and it
only contains one class. I've tried to dig around in Spark's source
code without getting any smarter. My views look like this:

Index.spark:

<use master="Site"/>
Hello from spark!

Site.spark

Spark layout here!

I've also tried including a <use content="view"/> in Site.spark and
then <content name="view">...</content> in Index.spark, but that makes
no difference. Only Site.spark is being compiled still.

It's also a problem for me that the compiled views are named by GUID,
since that makes it impossible to find the correct view for a given
view path that comes in to my VirtualPathProvider and
ControllerFactory. Can't the compiled views be named (in my case) like
so:

MyApp.Views.Home.Index
MyApp.Views.Shared.Site

or is this somehow impossible? The best thing would be to be able to
configure this in the SparkBatchDescriptor.


-Asbjørn

Asbjørn Ulsberg

unread,
Jun 9, 2010, 7:50:38 AM6/9/10
to Spark View Engine Dev
Okay, I've had progress! I realised my Spark view syntax knowledge had
some pretty major holes in it and I've now managed to compile all of
the views used in a controller like so:

e.Batch.For<HomeController>().Layout("Site").Include("*");

This produces an assembly of pre-compiled ISparkViews. This is all
fine and dandy. The problem now lies in:

1. Finding the right ISparkView to render for the given context.
2. Actually rendering the view.

Number 1 is partially solved by doing
sparkViewFactory.Engine.LoadBatchCompilation(Assembly.Load(viewAssemblyName))
and then querying
viewEngine.CompiledViewHolder.Current.Lookup(descriptor). My issue
with this is:

1. The "TargetNamespace" is for some reason set to
"My.Assembly.Controllers". Where does "Controllers" come from and how
do I affect (or detect) what it is?
2. What I get back is a ISparkViewEntry that I can call
CreateInstance() on to get an ISparkView.

My problem with ISparkView is that it for whatever completely non-
obvious reason doesn't inherit System.Web.Mvc.IView. Why doesn't it?
It exposes a Render() method just like IView. While IView would be
portable across any project that does or doesn't know that Spark even
exists, ISparkView isn't portable at all. Why did you make this design
decision of not inheriting System.Web.Mvc.IView?


-Asbjørn

Asbjørn Ulsberg

unread,
Jun 9, 2010, 8:03:02 AM6/9/10
to Spark View Engine Dev
I also have to wonder why SparkViewEngine.CompiledViewHolder.Lookup()
doesn't work (it contains 0 items) while
SparkViewEngine.CompiledViewHolder.Current.Lookup() does. In what
other contexts than a static one would CompiledViewHolder.Current be
useful and why do you need to use it by default?

PS: Am I alone on this list or is it just coincidental that there's
been 0 replies to this thread for the last 1+ week?

-Asbjørn

Howard van Rooijen

unread,
Jun 9, 2010, 9:41:37 AM6/9/10
to spar...@googlegroups.com
Don't think you're alone - just think you're dabbling in some esoteric parts of Spark that folks may not have experience in (I dont!)

/Howard

2010/6/9 Asbjørn Ulsberg <asbj...@gmail.com>
--
You received this message because you are subscribed to the Google Groups "Spark View Engine Dev" group.
To post to this group, send email to spar...@googlegroups.com.
To unsubscribe from this group, send email to spark-dev+...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/spark-dev?hl=en.


Rob G

unread,
Jun 9, 2010, 10:23:16 AM6/9/10
to spar...@googlegroups.com
Hi Asbjørn,

It looks like the decision to not make ISparkView inherit from System.Web.Mvc.IView is because IView is Microsoft specific. The Spark view engine doesn't only work with Microsoft MVC, but also with Ruby, Python, Javascript, MonoRail as well as "Stand Alone" - for doing things like rendering out HTML email for example. None of those solutions have anything to do with MS MVC, and so it doesn't make sense to build that dependency in. I understand that may make you life a little easier but there are other ways to do what you are trying to do.

If I have time, I'll try and look a little deeper into your problem but there may be something that can help. I built the Spark integration and a custom view locator for the FubuMVC project which locates views and assigns them to Controllers as the application is bootstrapping. I know it's a long shot, but perhaps have a look at the code here (http://github.com/RobertTheGrey/fubumvc/tree/master/src/Spark.Web.FubuMVC/) and see if you can spot something I did that may help you understand the inner workings of Descriptors and Batch handlers. The magic is in the Descriptors ;-)

Hope that helps...
All the best,
RobertTheGrey

2010/6/9 Asbjørn Ulsberg <asbj...@gmail.com>

Asbjørn Ulsberg

unread,
Jun 16, 2010, 3:30:48 AM6/16/10
to spar...@googlegroups.com, Rob G
Hi and thanks for your reply, Rob.

Yea, I get the ISparkView not inheriting from IView part. I didn't think
about the other contexts Spark was usable when I wrote the e-mail, but
they are of course important and obvious when you think of them.

What I did discover, though, was that although what was returned from
ISparkViewEntry.CreateInstance() was ISparkView, the actual implementation
was Spark.Web.Mvc.SparkView which implements IView! So I can cast the
object returned from CreateInstance() to IView and treat it as such from
that point on, which creates the loose coupling I was aiming for.

I'm now also able to locate views in the CompiledViewHolder through the
following rather obscure (and too "Magic Strings" based for my taste)
SparkViewDescriptor:

string controller = context.RouteData.GetRequiredString("Controller");
string templateName = String.Format(@"{0}\{1}.spark", controller,
viewName);
string targetNamespace = String.Concat(GetType().Namespace,
".Controllers");

SparkViewDescriptor descriptor = new SparkViewDescriptor
{
Language = LanguageType.Default,
TargetNamespace = targetNamespace,
Templates = new[] { templateName, SharedSiteTemplate },
};

It would be so much better if we could just query based on
ControllerContext, ViewContext or something similar so Spark itself can do
this magic string concatenation based on its internal conventions which
imho shouldn't be known to the outside world. For instance, why do I need
to append '.Controllers' to the namespace?

Anyhoo, this works and I'm (fairly) happy. :)

-Asbjørn

>> spark-dev+...@googlegroups.com<spark-dev%2Bunsu...@googlegroups.com>

Reply all
Reply to author
Forward
0 new messages