Conventional configuration pseudo code

2 views
Skip to first unread message

Mark Nijhof

unread,
Sep 20, 2009, 2:41:46 PM9/20/09
to FubuMVC Development Group
Hi Guys,

Before I start implementing this I want to show you some pseudo code
to get some early reactions. Apologies for the huge code blocks ...

There are (currently) three main interfaces that could be implemented
and provide the configuration

public interface IUrlActionScannerConvention
public interface IUrlActionBuilderConvention
public interface ISetupUrlActionConventions

The rest of the code is a short idea n how it could be implemented. I
am thinking about having my own semantic model to 'prepare' everything
and then create it in one go.

Please let me know what you guys think.

-Mark

---- Huge code block :) ----

namespace FubuMVC.Configuration.Conventional.Conventions
{
public interface IUrlActionScannerConvention
{
void Apply(IUrlActionScanner urlActionScanner);
}

public class AddsUrlActionsForPublicSite : IUrlActionScannerConvention
{
public void Apply(IUrlActionScanner urlActionScanner)
{
urlActionScanner
.AddFromAssembly<Object>()
.Where(x =>
x.Namespace.StartsWith("Some.NameSpace.UrlActions"));
}
}

public class AddsUrlActionsForAdminSite : IUrlActionScannerConvention
{
public void Apply(IUrlActionScanner urlActionScanner)
{
urlActionScanner
.AddFromAssembly<Object>()
.Where(x =>
x.Namespace.StartsWith("Some.NameSpace.Admin.UrlActions"));
}
}
}

namespace FubuMVC.Configuration.Conventional.SemanticModel
{
public interface IUrlActionScanner
{
void Add(Type urlActionType);
ITypeFilter AddFromAssembly<TTypeInAssembly>() where
TTypeInAssembly : class;
}

public class UrlActionScanner : IUrlActionScanner
{
public void Add(Type urlActionType)
{
// Add to Semantic Model
// Trigger the ISetupUrlActionConventions
// Trigger the IOverrideUrlActions
}

public ITypeFilter AddFromAssembly<TTypeInAssembly>() where
TTypeInAssembly : class
{
return new AddUrlActionTypeFilter<TTypeInAssembly>(this);
}
}

public class AddUrlActionTypeFilter<TTypeInAssembly> : ITypeFilter
{
private readonly Assembly _assembly;
private readonly IUrlActionScanner _urlActionScanner;

public AddUrlActionTypeFilter(IUrlActionScanner urlActionScanner)
{
_urlActionScanner = urlActionScanner;
_assembly = typeof(TTypeInAssembly).Assembly;
}

public void Where(Func<Type, bool> evalTypeFunction)
{
_assembly.GetExportedTypes().Each(type =>
{
if (type.IsAbstract) return;
if (type.IsValueType) return;
if (!type.IsInstanceOfType(typeof(UrlAction))) return;

if (evalTypeFunction(type)) _urlActionScanner.Add(type);
});
}
}
}

namespace FubuMVC.Configuration.Conventional.Conventions
{
public interface IUrlActionBuilderConvention
{
void Apply(IUrlActionBuilder urlActionBuilder);
}

public class CreateUrlActionsForPublicSite : IUrlActionBuilderConvention
{
public void Apply(IUrlActionBuilder urlActionBuilder)
{
urlActionBuilder
.AddFromAssembly<Object>()
.Where(x =>
x.Namespace.StartsWith("Some.NameSpace.UrlActions"));
}
}

public class CreateUrlActionsForAdminSite : IUrlActionBuilderConvention
{
public void Apply(IUrlActionBuilder urlActionBuilder)
{
urlActionBuilder
.AddFromAssembly<Object>()
.Where(x =>
x.Namespace.StartsWith("Some.NameSpace.Admin.UrlActions"));
}
}
}

namespace FubuMVC.Configuration.Conventional.SemanticModel
{
public interface IUrlActionBuilder
{
void Add(UrlAction urlAction);
ITypeFilter AddFromAssembly<TTypeInAssembly>() where
TTypeInAssembly : class;
Func<Type, UrlAction> UrlActionBuildFunction { get; set; }
string ViewToRender { get; set; }
void AddBehavior<TBehavior>();
}

public class UrlActionBuilder : IUrlActionBuilder
{
public Func<Type, UrlAction> UrlActionBuildFunction { get; set; }
public string ViewToRender { get; set; }

public UrlActionBuilder()
{
UrlActionBuildFunction = type => new UrlAction{
PrimaryUrlStub = type.Name };
}

public void Add(UrlAction urlAction)
{
// Add to Semantic Model
// Trigger the ISetupUrlActionConventions
// Trigger the IOverrideUrlActions
}

public ITypeFilter AddFromAssembly<TTypeInAssembly>() where
TTypeInAssembly : class
{
return new BuildUrlActionTypeFilter<TTypeInAssembly>(this);
}

public void AddBehavior<TBehavior>()
{

}
}

public class BuildUrlActionTypeFilter<TTypeInAssembly> : ITypeFilter
{
private readonly Assembly _assembly;
private readonly IUrlActionBuilder _urlActionBuilder;

public BuildUrlActionTypeFilter(IUrlActionBuilder urlActionBuilder)
{
_urlActionBuilder = urlActionBuilder;
_assembly = typeof(TTypeInAssembly).Assembly;
}

public void Where(Func<Type, bool> evalTypeFunction)
{
_assembly.GetExportedTypes().Each(type =>
{
if (type.IsAbstract) return;
if (type.IsValueType) return;
if (!type.IsInstanceOfType(typeof(UrlAction))) return;

if (!evalTypeFunction(type)) return;


_urlActionBuilder.Add(_urlActionBuilder.UrlActionBuildFunction(type));
});
}
}
}

namespace FubuMVC.Configuration.Conventional.SemanticModel
{
public interface ITypeFilter
{
void Where(Func<Type, bool> evalTypeFunction);
}
}

namespace FubuMVC.Configuration.Conventional.Conventions
{
public interface ISetupUrlActionConventions
{
void Apply(Type urlActionOrControllerType, IUrlActionBuilder
urlActionBuilder);
}

public class SetupUrlActionsForPublicSite : ISetupUrlActionConventions
{
public void Apply(Type urlActionOrControllerType,
IUrlActionBuilder urlActionBuilder)
{
if (!urlActionOrControllerType.Namespace.StartsWith("Some.NameSpace.UrlActions"))
return;

urlActionBuilder.ViewToRender =
"~/Views/{0}/index".ToFormat(urlActionOrControllerType.Name);
urlActionBuilder.AddBehavior<Object>();
}
}

public class SetupUrlActionsForAdminSite : ISetupUrlActionConventions
{
public void Apply(Type urlActionOrControllerType,
IUrlActionBuilder urlActionBuilder)
{
if (!urlActionOrControllerType.Namespace.StartsWith("Some.NameSpace.Admin.UrlActions"))
return;

urlActionBuilder.ViewToRender =
"~/Views/admin/{0}/index".ToFormat(urlActionOrControllerType.Name);
urlActionBuilder.AddBehavior<Object>();
urlActionBuilder.AddBehavior<Object>();

}
}
}

Mark Nijhof

unread,
Sep 20, 2009, 6:38:28 PM9/20/09
to FubuMVC Development Group
For convenience I just zipped the project I quickly created for this
mock-up so you can use that and use VS to navigate. This takes a
dependency on the Branch that Chad created, not the trunk, but
navigation should work ithout it as well.

On other thing currently there are only three conventions but I am
thinking that this will expand quit a bit, and also that you could
have three different implementations of the same convention
configuring different elements of your actions. F.ex. one configures
the Views and an other one configures the behaviors that need to be
applied. And you may have noticed that there is not IUrlActionOverride
interface yet. This one is a little bit tricky for when you use the
IUrlActionBuilderConvention because I don't know yet how to identify
one UrlAction except by its Url I guess, but that seems a little bit
flacky.

Also currently all I am thinking on running all conventions for each
UrlAction that gets added, I am thinking that this could perhaps be
more elegantly done after the adding of UrlActions but then again I
need a good way of identifying the UrlAction. So what would you guys
think of adding the type and when available the method information to
the UrlAction that where used to build the UrlAction? F.ex. A
controller with multiple actions would result in multiple UrlActions
all containing the controller type and particular method, if it is
only a UrlAction that determined this than type would be itself
without a method information. This way I can split up the scanning of
the UrlActions from setting them up, but still use the same type based
conventions to determine if and how to apply the setup conventions.
Make sense?

-Mark

FubuMVC.Configuration.Conventional.zip

Dru Sellers

unread,
Sep 21, 2009, 9:13:23 AM9/21/09
to fubumv...@googlegroups.com
not to be nitpicky, but what would a result sample config look like?
-d

Dru Sellers

unread,
Sep 21, 2009, 9:13:33 AM9/21/09
to fubumv...@googlegroups.com
and lazy.

Mark Nijhof

unread,
Sep 21, 2009, 10:27:48 AM9/21/09
to fubumv...@googlegroups.com
I'll get you an example config tomorrow. In the mean time there are a
few implementations of the conventions already written down in the
first e-mail. Basically think about just auto scanning for these
conventions in a provided assembly.

-Mark

Mark Nijhof

unread,
Sep 24, 2009, 8:47:35 PM9/24/09
to fubumv...@googlegroups.com
I didn't get a change to get an actual example for the configuration
but think of something like this:

Conventional.Configuration(x => {
x.LoadAddUrlConentionsFromAssembly<AClassInTheAssembly>();
x.LoadAddUrlConentionsFromAssembly<AClassInOtherAssembly>();

x.LoadSetupConventionsFromAssembly<AClassInTheAssembly>();
x.LoadOverridesFromAssembly<AClassInTheAssembly>();

x.Build();
});

No other input?

-Mark

Dru Sellers

unread,
Sep 24, 2009, 8:50:56 PM9/24/09
to fubumv...@googlegroups.com
LoadAdd is a bit awkward.

I would use one or the other

why do I have to call build, just have the build happen after you leave the closure?

-d

Mark Nijhof

unread,
Sep 24, 2009, 8:56:46 PM9/24/09
to fubumv...@googlegroups.com
Both comments are good, it is late here ;)

But can you see the conventional stuff working for you, or is it too
far out there?

-Mark

Dru Sellers

unread,
Sep 24, 2009, 10:13:18 PM9/24/09
to fubumv...@googlegroups.com
not sure. have to chew. but polish is always good.
we can always refactor it later. ;)
-d

Mark Nijhof

unread,
Nov 3, 2009, 5:24:28 AM11/3/09
to FubuMVC Development Group
No one else has any comments on the conventional stuff?

-Mark


On Sep 25, 3:13 am, Dru Sellers <d...@drusellers.com> wrote:
> not sure. have to chew. but polish is always good.we can always refactor it
> later. ;)
> -d
>
>
>
> On Thu, Sep 24, 2009 at 7:56 PM, Mark Nijhof <mark.nij...@gmail.com> wrote:
>
> > Both comments are good, it is late here ;)
>
> > But can you see the conventional stuff working for you, or is it too
> > far out there?
>
> > -Mark
>
> > On Fri, Sep 25, 2009 at 2:50 AM, Dru Sellers <d...@drusellers.com> wrote:
> > > LoadAdd is a bit awkward.
> > > I would use one or the other
> > > why do I have to call build, just have the build happen after you leave
> > the
> > > closure?
> > > -d
>
> > > On Thu, Sep 24, 2009 at 7:47 PM, Mark Nijhof <mark.nij...@gmail.com>
> > wrote:
>
> > >> I didn't get a change to get an actual example for the configuration
> > >> but think of something like this:
>
> > >> Conventional.Configuration(x => {
> > >>  x.LoadAddUrlConentionsFromAssembly<AClassInTheAssembly>();
> > >>  x.LoadAddUrlConentionsFromAssembly<AClassInOtherAssembly>();
>
> > >>  x.LoadSetupConventionsFromAssembly<AClassInTheAssembly>();
> > >>  x.LoadOverridesFromAssembly<AClassInTheAssembly>();
>
> > >>  x.Build();
> > >> });
>
> > >> No other input?
>
> > >> -Mark
>
> > >> On Mon, Sep 21, 2009 at 4:27 PM, Mark Nijhof <mark.nij...@gmail.com>
> > >> wrote:
> > >> > I'll get you an example config tomorrow. In the mean time there are a
> > >> > few implementations of the conventions already written down in the
> > >> > first e-mail. Basically think about just auto scanning for these
> > >> > conventions in a provided assembly.
>
> > >> > -Mark
>
> > >> > On Mon, Sep 21, 2009 at 3:13 PM, Dru Sellers <d...@drusellers.com>
> > wrote:
> > >> >> and lazy.
>
> > >> >> On Sun, Sep 20, 2009 at 5:38 PM, Mark Nijhof <mark.nij...@gmail.com>
> > >> >>> On Sun, Sep 20, 2009 at 8:41 PM, Mark Nijhof <mark.nij...@gmail.com
> ...
>
> read more »

Dru Sellers

unread,
Nov 3, 2009, 5:27:56 AM11/3/09
to fubumv...@googlegroups.com
man its been quite a while so I say, no. ;)
-d

Mark Nijhof

unread,
Nov 3, 2009, 7:07:56 AM11/3/09
to fubumv...@googlegroups.com
Hehe I was hoping for some input then got side tracked. Is it still
valuable to do so, as it seems the project is very quit. (I am to
blame there as well of course).

-Mark

Dru Sellers

unread,
Nov 3, 2009, 7:09:49 AM11/3/09
to fubumv...@googlegroups.com
I say go for it. 
when you are done I will upgrade on wednesday and give feed back.
-d

Mark Nijhof

unread,
Nov 3, 2009, 7:11:26 AM11/3/09
to fubumv...@googlegroups.com
Hehe no pressure do, Wednesday afternoon vs morning will be fine.

Dru Sellers

unread,
Nov 3, 2009, 7:16:49 AM11/3/09
to fubumv...@googlegroups.com
:)

Ryan Kelley

unread,
Nov 3, 2009, 9:36:06 AM11/3/09
to fubumv...@googlegroups.com
I will give feedback today, promise. I have been super busy and just haven't had a chance, but will make time for you today!

-Ryan
Reply all
Reply to author
Forward
0 new messages