kenegozi.com

<form id='kenegozi' action='post'></form>

   
2008 Jul 19

MonoRail sample gone AspView

tagged as: castle | monorail | aspview

Some more AspView love:

This dude, Morten Lyhr (great blog - go on and subscribe), has taken the sample MonoRail Getting Started project and AspView-ed it.

 

Take a look.

2008 Jul 16

I didn't brake the build

tagged as: castle | monorail | aspview

After making it build locally and reaching the conclusion that AspView builds correctly as part of the main Castle build , I've commited the changes to the repository, and the build server appear to agree with me:

Build_Succeded_on_the_build_server

2008 Jul 16

Build Succeeded - A happy red screen

tagged as: castle | monorail | aspview

can you guess why this makes me happy?

Build_Succeded

This is the output of building Castle's trunk, both for .NET 3.5 and .NET 2.0, after inserting AspView into the core project. Took me a while as I had to:

  1. Change the Xunit tests into NUnit - to match the runner
    wasn't too complicated, though I has to manually add [SetUp] and [TestFixture] everywhere, as they're not needed in Xunit
  2. Setting the correct Castle license snippet on every file
  3. Making the build pass and run all the tests correctly.
    now that was a royal PITA, as part of the tests include compiling view templates from source files, and copying files to the build folder using NANT is not simple, as the <copy> task flattens the source directory structure. For now I settled on specifying each views folder in the build file but Im looking at improving that bit.

So, soon enough (hopefully by the end of this day) you'd be able to see AspView on the build server.

 

Thx again for all of the users and patch-contributors for your faith in this library.

2008 Jul 12

Building Castle on Vista

tagged as: castle

So after moving to Vista last week, I've tried a full castle build with tests.

 

Things I had to take care for it to run properly (from easy to not-as):

  1. Make sure Nant is in the path
  2. Make sure that NUnit 2.2.x is in the path
    explanation: for some reason, the remoting tests fail when being run from NUnit 2.4.x   As I'd rather not to gac any specific NUnit version, I have on my C:\Program Files two separate directories, one called "NUnit 2.2.8" and one called "NUnit 2.4.7", and the shortcut I use for firing a Command Prompt for Castle is making sure that NUnit 2.2.8 is in the path.
  3. Setup the test databases for DB related integration tests (as explained in "How To Build.txt")
  4. Make sure that you use an elevated command prompt - the shortcut I've mentioned on 2. is set as "Run As Administrator"
  5. To make the WcfIntegration facility tests run correctly, you need to run this thing once:
    sc.exe config NetTcpPortSharing start= demand
  6. some config files are missing from the build folder (Castle\build). until we fix it in the nant script, you have to manually run
    copy ..\Facilities\Wcf\Castle.Facilities.WcfIntegration.Tests\Configure*.xml ..\Build

 

Now that I have a way to run the build and make sure all tests pass, I can start working on my next Castle assignment - bringing AspView into the core project, but that's a whole other post so keep your RSS reader open ...

2008 Jun 28

FileBinderAttribute to ease FileUpload in MonoRail

tagged as: asp.net 2.0 | c# | castle | monorail

Following Scott Hanselman's post on FileUpload in ASP.NET MVC, I'll add here a few bits on doing that in MonoRail.

 

First, as MonoRail is an extension on top of plain ol' ASP.NET, just as ASP.NET MVC is, you can do the exact same thing - i.e iterate over Request.Files, and use a mocked Files collection for test or something.

 

But as the action parameters binder is very smart, and easily extensible, it's even nicer to just bind the posted data to a HttpPostedFile, using a FileBinder:

 

   1:  [AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)]
2: public class FileBinderAttribute: Attribute, IParameterBinder
3: {
4: public int CalculateParamPoints(IEngineContext context, IController controller, IControllerContext controllerContext, ParameterInfo parameterInfo)
5: {
6: var key = parameterInfo.Name;
7: return context.Request.Files[key] != null ? 10 : 0;
8: }
9:  
10: public object Bind(IEngineContext context, IController controller, IControllerContext controllerContext, ParameterInfo parameterInfo)
11: {
12: var key = parameterInfo.Name;
13: return context.Request.Files[key] as HttpPostedFile;
14: }
15: }

 

So a custom binder is an attribute, that implements IParameterBinder, a two methods interface:

  1. CalculateParamPoints() - is for helping the framework correctly guess the best candidate of the action overloads. If the file exists in the request then it makes an action with a HttpPostedFile parameter with the name of the file upload name, a better candidate than an overload with a String parameter with the same name.
  2. Bind() - well, kinda' self explanatory.

 

so now you're action can look like this:

   1:  public void Save([FileBinder] HttpPostedFile myfile)
2: {
3: if (myFile != null)
4: {
5: // do stuff with the file
6: }
7: }

 

Cool? well actually what really is cool is that binding to HttpPostedFile is baked into MonoRail to begin with - so you don't even need this FileBinderAttribute at all ! you can simply

   1:  public void Save(HttpPostedFile myfile)
2: {
3: if (myFile != null)
4: {
5: // do stuff with the file
6: }
7: }

 

So why did I show you that?

Testablility.

Since HttpPostedFile is not easily mockable* (cuz it's bloody sealed and not new-able), you should do what you always do when in need to bypass one of these un-testable hard-to-test* sealed classes: Adapter pattern. Introduce IHttpPostedFile, and supply your own HttpPostedFile encapsulating the built in one.

 

so:

1: [AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)]
2: public class FileBinderAttribute: Attribute, IParameterBinder
3: {
4: public int CalculateParamPoints(IEngineContext context, IController controller, IControllerContext controllerContext, ParameterInfo parameterInfo)
5: {
6: var key = parameterInfo.Name;
7: return context.Request.Files[key] != null ? 10 : 0;
8: }
9:  
10: public object Bind(IEngineContext context, IController controller, IControllerContext controllerContext, ParameterInfo parameterInfo)
11: {
12: var key = parameterInfo.Name;

13: var file = context.Request.Files[key] as HttpPostedFile;
14: return file == null ? null : HttpPostedFileAdapter(file);
15: }
16: }

 

and

   1:  public void Save([FileBinder] IHttpPostedFile myfile)
2: {
3: if (myFile != null)
4: {
5: // do stuff with the file
6: }
7: }

 

 

 

 

 

 

* Yes Roy, I know you can throw some TypeMock magic at it

2008 Jun 22

Castle.Tools.* in Castle Contrib's repository has moved a bit

tagged as: css | html | tools | castle | SQL Server

The tools (various small helper libraries) are now under http://svn.castleproject.org:8080/svn/castlecontrib/Tools/

 

what's in there:

  1. Castle.Tools.StaticMapGenerator - That one creates a typed tree representing js/css/image files on the site's filesystem.
    more here:
    http://www.kenegozi.com/Blog/2008/01/17/staticmapgenerator-for-asp-dot-net-first-teaser.aspx
    Which reminds me that I need to add .swf files to the mix ...
  2. Castle.Tools.SQLQueryGenerator -  That one is for building plain old SQL strings in a typed and intellisense friendly way.
    more here:
    http://www.kenegozi.com/Blog/2008/01/27/already-added-stuff-to-sql-query-generator.aspx
  3. Castle.Tools.QuerySpecBuilder/ - The new kid in the block. That's a tool that is used to build specs programmatically, which would later be translated to a SQL string for your flavour of DAL. The generated SQL is mostly ANSI compliant, apart from the Paging syntax which is TSQL only currently, but at some point I'll add an extension point to allow other syntaxes.
    I also have an external thing to make it extremely useful with NHibernate's ISQLQuery.
    I'll blog about all that when I'll have a little time.
2008 May 14

MonoRail talk at The Developers Group

tagged as: architecture | castle | monorail | aspview

Have just came back from my talk, given for The Developers Group in Microsoft's Victoria offices, London UK.

 

Took me a bit to find the place, as the building does not say "Microsoft" on the outside (as opposed to the offices in Israel).

 

The presentation went pretty much ok, considering it was my first time actually presenting in English, in front of an English crowd, and considering I had a PC malfunction that has forced me to recreate the Demo project, on the train today ... Just finished it up 5 seconds before connection the laptop to the projector.

 

I didn't manage to squeeze in some of the parts that I wanted to, like JSONReturnBinder and Windsor integration, and like Unit-Testing controllers and views, but I do hope that I managed to do justice with this wonderful stack, within the limited time and my horrible English ...

 

Unfortunately, I missed the post-meeting-pub-thing as I just happened to leave the place last and didn't see where everyone did go, so if you were there and has some questions, please do not hesitate to leave them here as comments.

 

Anyway, as promised, here are the slides and the demo project.

 

If you are using git, and have a git-hub account, then you would be able to follow the demo project's source at http://github.com/kenegozi/monorail-aspview-demo/tree/master

 

Have fun.

 

P.S

I'd like to thank Jason from The Developers Group, and Nina from Microsoft, who have helped with the administration part of things. Everything went smooth despite my late arrival. I'd also like to thank the attendees for their patience and listening. I hope you've enjoyed it, I definitely have :) 

2008 May 9

Using nhibernate's named queries with ActiveRecord

tagged as: castle | activerecord | nhibernate | hql

One of the methods of querying the DB when using NHibernate, is to issue HQL queries. HQL stands for "Hibernate Query Language". It has a SQL-like syntax and is very intuitive for people with SQL background.

 

The way this works is that NHibernate 'compiles' the HQL query into SQL, and then issues the SQL query (using ADO.NET's facilities) to the DB.

 

Sounds pricey?

enter Named Queries.

now these are HQL (or SQL) queries, each has a name (obviously), that are been supplied to NH through the mapping. The queries are being translated and cached as IDbCommand objects as part of the framework initialisation, which mean that you get rid of the HQL->SQL overhead throughout the life of the process.

 

One other major benefit, is that the mechanism to actually execute these named queries, does not differentiate between HQL and SQL queries (for the simple fact that these queries have already been transferred to SQL at runtime). That gives you the possibility to replace HQL queries into tighter SQL queries (with the same parameters and which returns the same resultset) should your DBA figure out a better one.

 

But if you're using ActiveRecord, you usually do not have direct access into the mapping (.hbm) files. So how would you use named queries with AR?

 

enter HqlNamedQueryAttribute (not such a great name, as I did state that it would also work for SQL queries).

 

So, for an example, on this blog's source code, within PostRepository.cs you'd see this code:

...

 

#region queries
[assembly: HqlNamedQuery(Queries.FindPostsInArchive, Queries.FindPostsInArchive)]
[assembly: HqlNamedQuery(Queries.FindByUrlFriendlyTagName, Queries.FindByUrlFriendlyTagName)]
namespace KenEgozi.Com.Domain
{
    internal partial class Queries
    {
        internal const string FindPostsInArchive = @"
                from Post p
                where
                    year(p.Lifecycle.CreationDate) = :year and
                    month(p.Lifecycle.CreationDate) = :month
                order by p.Lifecycle.CreationDate desc";
        internal const string FindByUrlFriendlyTagName = @"
                select p
                from
                            Post p
                    join    p.Tags t
                where t.UrlFriendlyName like :urlFriendlyTagName
                order by p.Lifecycle.CreationDate desc;";
    }
}
#endregion

...

 

        public ICollection<Post> FindInArchive(int year, int month)
        {

            return session
                .GetNamedQuery(Queries.FindPostsInArchive)
                .SetParameter("year", year)
                .SetParameter("month", month)
                .List<Post>();
        }

...

Queries class is marked as partial, as other queries might be presented on other repositories or services that would need to add more named queries. I considered grouping of queries into groups by the using repository, or by aggregate roots, but the thing is - having all of the queries under the same namespace helps discoverability, and helps with preventing duplications

2008 Mar 4

The strength to document the complex

tagged as: castle

Another funny quote from Castle dev list:

Ayende (after a discussion on the lack of DynamicProxy documentation):
Yes, the underlying assumption that by the time you are done understanding DP you don't have the strength to write docs.

 

If you wanna grok that, then you can look at a small snippet from DP2 code on the blog's title, or browse the repo

2008 Mar 2

Documenting Castle, or Thank you Symon Rottem

tagged as: miscellanea | castle

We, at Castle, are occasionally getting bashed at the lack of documentation. I think that the area most users are complaining about is Windsor and MonoRail, (as these two are evolving in the most rapid way).

My personal view on the matter is that since the whole Castle stack, and especially MonoRail and Windsor, are all about "zero friction" and "Convention over Configuration", the easiest way is to lay hands on sample or oss code and apply that you your solution.

 

Anyway, in the Alt.NET uk thing that was at Conchango/London last month I've met one Symon Rottem. It appear that this guy know his way around tech-docs, and he had picked up that errand, and started putting effort in improving the overall documentation level for Castle, especially the User-Manual part (as the API actually is being generated and is quite good).

 

I'd also recommend his (young yet promising) blog. It's on my Google-reader blogroll for quite some time, and I really need to add "Import OPML" to my blog so I'd be able to update the blogs list on the side panel here.

2008 Mar 1

Windsor - Mass Component Registration

tagged as: castle

It's so awesome.

I have about 1 minute for that, and the code is very self explanatory, so Im just doing a Copy&Paste from the Castle dev list:

 

Craig Neuwirt:

The recent changes to the kernel registration interface allows for custom registration strategies.   I just added an AllTypesOf strategy to allow for the most common scenarios. 
Here are some examples:

  • Registering all controllers in the current assembly 
    kernel.Register( AllTypesOf<IController>
         .FromAssembly( Assembly.GetExecutingAssembly() )
          );
  • selecting the first interface as the service
    kernel.Register( AllTypesOf<ICommon>
          .FromAssembly(Assembly.GetExecutingAssembly() )
          .WithService.FirstInterface()
           );
  • Using custom configuration
    kernel.Register( AllTypesOf<ICommon>
          .FromAssembly( Assembly.GetExecutingAssembly() )
          .Configure( component => component.LifeStyle.Transient
                                .Named( component.Implementation.FullName + "XYZ" )
                                )
           );
  • Choosing types if they have a specific attribute (courtesy of LINQ)
    kernel.Register( AllTypesOf<CustomerChain1>
            .Pick( from type in Assembly.GetExecutingAssembly().GetExportedTypes()
                     where type.IsDefined(typeof(SerializableAttribute), true)
                     select type
                     ));

Ayende:

You are taking all the fun out of Binsor :-)

2008 Feb 28

Executing Plain ol' SQL in ActiveRecord Transaction

tagged as: castle | activerecord

I'm getting asked for this a lot (lately on the Castle's usergroup, and on many other occasions)

 

You friend is ActiveRecordMediator.Execute

 

So here is a sample:

ActiveRecordMediator.Execute(typeof(ActiveRecordBase), delegate (NHIbernate.ISession session, object data)
{
   IDbConnection con = session.Connection;
   IDbCommand cmd = con.CreateCommand();

 

// That's the key part - joining the current AR transaction scope
   session.Transaction.Enlist(cmd);  

 

// now you have a IDbCommand instance - use it at will


}, null);

If you want to create a proper method for handling the delegate instead of the anonymous one, then you can pass data in there (using the third argument) and it would get into the delegate as the "object data" thing.

2008 Feb 12

Castle Docs Help

tagged as: castle | Alt.NET UK

Lately there has been some noise around the lack of documentation on the Castle project.

 

I have expressed my view on the matter on the mailing list, and in short I'd say that having an undocumented feature is way better than not having that feature at all.

 

During the ALT.NET UK conference, one of the guys approached me and said that he has solid background in technical documentation, and that he is willing to put some effort to that end.

 

I'm terrible with names, so I forgot his (sorry ...), but if it's you dear reader (or if it's not you, but you are willing to help with that) then please do contact me should you need any help in kicking it off.

 

Thanks a bunch,

Ken.

2008 Jan 17

StaticMapGenerator Source Is Available

tagged as: asp.net 2.0 | tools | castle

The Static SiteMap Generator's home is in Castle Contrib, and it's named Castle.Tools.StaticMapGenerator

 

I've just commited it to the repository, so it's at http://svn.castleproject.org:8080/svn/castlecontrib/Castle.Tools.StaticMapGenerator/trunk/

 

UPDATE (22/06/2008):
The source has slightly moved (to a sub folder):
http://svn.castleproject.org:8080/svn/castlecontrib/Tools/Castle.Tools.StaticMapGenerator/

 

I hope to have time soon to blog about the creation of this little tool, and of the usage. Also, expect a binary soon.

2008 Jan 17

It's My Turn To Build An IoC Container In 15 Minutes and 33 Lines

tagged as: architecture | tools | castle

Last night I've built a nice new tool called StaticMapGenerator which is used to generate a typed static resources site-map for ASP.NET sites (works for MonoRail, ASP.NET MVC and even WebForms).

I'll blog about it on a separate post in details.

Since I didn't want any dependency (but .NET 2.0 runtime) for the generator and the generated code, I couldn't use Windsor to IoC. That calls for a hand rolled simple IoC implementation

Ayende has already done it in 15 lines, but I wanted also to automagically set dependencies and have a simpler registration model.

so I've quickly hacked together a configurable DI resolver (a.k.a. IoC container) in 15 Minutes and 33 Lines Of Code. Call me a sloppy-coder, call me whadever-ya-like. It just works.

static class IoC 
{
   static readonly IDictionary<Type, Type> types = new Dictionary<Type, Type>();
  
   public static void Register<TContract, TImplementation>()
   {
      types[typeof(TContract)] = typeof(TImplementation);
   }
  
   public static T Resolve<T>()
   {
      return (T)Resolve(typeof(T));
   }

  
   public static object Resolve(Type contract)
   {
      Type implementation = types[contract];
  
      ConstructorInfo constructor = implementation.GetConstructors()[0];
  
      ParameterInfo[] constructorParameters = constructor.GetParameters();
  
      if (constructorParameters.Length == 0)
         return Activator.CreateInstance(implementation);
  
      List<object> parameters = new List<object>(constructorParameters.Length);
  
      foreach (ParameterInfo parameterInfo in constructorParameters)
         parameters.Add(Resolve(parameterInfo.ParameterType));
  
      return constructor.Invoke(parameters.ToArray());
   }
}

Ok, I've cheated. You'd need using statements too, but you can see that I was generous enough with newlines ...

Usage:

Given those:

public interface IFileSystemAdapter { }
 
public class FileSystemAdapter : IFileSystemAdapter { }
 
public interface IBuildDirectoryStructureService { }
 
public class BuildDirectoryStructureService : IBuildDirectoryStructureService
{
   IFileSystemAdapter fileSystemAdapter;
   public BuildDirectoryStructureService(IFileSystemAdapter fileSystemAdapter)
   {
      this.fileSystemAdapter = fileSystemAdapter;
   } }

You can do that:

IoC.Register<IFileSystemAdapter, FileSystemAdapter>();
 
IoC.Register<IBuildDirectoryStructureService, BuildDirectoryStructureService>();
 
IBuildDirectoryStructureService service = IoC.Resolve<IBuildDirectoryStructureService>();
You need not worry about supplying the BuildDirectoryStructureService with an implementation for the service it depends on, but only to register an implementation for that service.
2008 Jan 7

AspView and the Latest Castle Trunk

tagged as: castle | monorail | aspview

Lately there has been a major refactoring work being done on MonoRail, as part of the effort toward a release hopefully later this year. As of today, AspView's trunk is once again compatible with Castle's trunk.

As usual, code's here, binaries are here.

2007 Dec 30

New Features For The New Year

tagged as: castle | monorail | aspview

In a good timing for the new year, I'm happy to announce new features to AspView.

I have dedicated a post for each so I'd have a way to reference those features, and for my dear readers to comment on each feature.

So, what's all the fuss about?

  1. Nested layouts
    http://www.kenegozi.com/Blog/2007/12/30/nested-layouts.aspx
  2. New syntax for html encoded output
    http://www.kenegozi.com/Blog/2007/12/30/html-encoded-output-in-view-templates.aspx
  3. Embedded script blocks inside a view
    http://www.kenegozi.com/Blog/2007/12/30/embedded-script-blocks.aspx
  4. Layouts from custom locations
    http://www.kenegozi.com/Blog/2007/12/30/using-layout-from-a-custom-location.aspx
  5. Not throwing on null-ref in <%= %> blocks
    http://www.kenegozi.com/Blog/2007/12/30/no-more-null-ref-(almost).aspx

Downloads, as always, are from www.aspview.com

2007 Dec 30

Nested Layouts

tagged as: castle | monorail | aspview

A cool feature, repeatedly asked for by users (of AspView, and of MonoRail in general).

 

When stating the layout name in the controller, you use a comma separated list of layouts to be applied, from the most general (outer) inward.

 

Example:

in the controller:

[Layout("Site, Admin")]
public class UsersController : SmartDispatcherController
{
    public void Index() { }
}

and given those schematic templates:

  • (layouts\site.aspx):
    SiteLayout
  • (layouts\admin.aspx)
    AdminLayout
  • (users\index.aspx)
    Index  

We'd get:

rendered view

2007 Dec 30

Embedded Script Blocks

tagged as: castle | monorail | aspview

Say  you want to have the possibility to create a method to work in views.

for the sake of argument, let it be:

public string DoubleId(string s)
{
    return s + s;
}

your options:

  1. Create a Helper class and put it there
  2. Create a base class and put it there

But what if it's simple enough (so you won't need a unit-test) and it's not supposed to be reused (so creating a Helper/Base class is an overkill)?

Now you can put it directly in your view template, and this is how:

<script runat="server">
public string DoubleId(string s)
{
    return s + s;
}
</script>

Regular view code
<%=DoubleIt(view.Name) %>

 

Now the devil advocates would say that "Logic In View Is Evil". And I would concur. But it's not actually logic. It's supposed to be used for view-related string manipulations and such. And anyway you can do Evil Deeds without it, too. And you don't HAVE to use it if you don't want to.

 

The idea (and 99% of implementation) is by Gauthier Segay. Thanks dude !

2007 Dec 30

Using Layout From a Custom Location

tagged as: castle | monorail | aspview

It's been asked on the Castle mailing list, and was implemented for NVelocity (and for Brail too, I think), so now it works on AspView, too.

 

So, doing:

[Layout("\custom\layout")] 
public class MyController ...

Would use the template from Views\Custom\Layout.aspx

2007 Dec 30

Html Encoded Output In View Templates

tagged as: castle | monorail | aspview

The existing <%= %> syntax would keep output the raw strings, so it can be used to output properties that has markup inside, like CMS data, the ViewContents in layouts, CaptureFor data, etc.

 

If you want http encoded output, use <%# %> or ${} instead.

 

Example:

Given the following view template:

<%
string markup = "<span>";
%>

<%=markup%>
<%#markup%>
${markup}

 

The rendered output would be:

<span>
&lt;span&gt;
&lt;span&gt;

 

Have fun.

2007 Dec 30

No More Null Ref (almost)

tagged as: castle | monorail | aspview

I found out that on many occasions I use stuff like:

<aspview:properties>
string message = "";
</aspview:properties>

To avoid the need of:

<% = message ?? "" %>

 

That's it.

From now on, null values would just be ignored.

 

Notice that it won't help you on

<%=post.Blog.Title %> if post.Blog is null ...

2007 Dec 21

XSS, HttpEncode, AspView and being Secure By Default

tagged as: architecture | castle | monorail | aspview

If you know not what XSS is or how easily you can expose your application to XSS, take a short read at the next posts:

AspView was written by me, for my (and my employer at the time) use. Therefore, I did not make it 'secure by default' in terms of HttpEncode.

 

However, seeing now that the convention lean toward outputing HtmlEncode-ed by default, I'm adapting AspView to that.

 

The usage would be similar to the one suggested for Asp.NET MVC at http://blog.codeville.net/2007/12/19/aspnet-mvc-prevent-xss-with-automatic-html-encoding/

 

So,

<%="<tag>" %> 

would output

&lt;tag&gt;

 

While

<%=RawHtml("<tag>") %>

would output

<tag>

 

The only exception here is ViewContents on layouts. since the view contents is 99% of the times made of markup, so in the layout would still write:

<%=ViewContents %> 

 

All of that stuff is being implemented with AspView trunk (versions 1.0.4.x) that works with Castle trunk.

If anyone wishes me to bubble it down to the 1.0.3.x branch (for Castle RC3), please leave your comments here. Unless I'll see that people actually want that I would probably not make the effort.

2007 Dec 13

New stuff in AspView

tagged as: castle | monorail | aspview

I'm pleased to announce that the first step of AspView refactoring is over. The pre-compilation process is now way more coherent and easy to follow and to test. Soon enough, as I'll complete adding a service locator to the mix, it would also be easily extensible.

 

What can you do now that you couldn't have done before? Use a custom base class for views.

For example: let's say that you have created a supercool helper. You'd probably name it SuperCoolHelper. Now you register that helper on the controller:

[Helper(typeof(SuperCoolHelper))]
public class MyController ...

 

You can, ofcourse declare it on every view:

<aspview:parameters>
<%
SuperCoolHelper SuperCoolHelper;
%>
</aspview:parameters>

<%=MyCoolHelper.CoolStuff() %>

You can also use the DictionaryAdapter and add the helper to the base view interface:

public interface IView
{
    SuperCoolHelper SuperCoolHelper { get; set; }
}

...

<% Page Language="C#" Inherits="Castle.MonoRail.Views.AspView.ViewAtDesignTime<IView>" %>

...
<%=view.MyCoolHelper.CoolStuff() %>

But now you can create a base class for the view:

The base class:

public class MyView : AspViewBase
{
    SuperCoolHelper SuperCoolHelper { get { return (SuperCoolHelper)Properties["SuperCoolHelper"]; } }
}

A mocked class that inherit from Web.UI.Page to make intellisense play nicely:

public class MyViewAtDesignTime : ViewAtDesignTime
{
    SuperCoolHelper SuperCoolHelper { get { throw new NotImplementedException("useless"); } }
}

and in the view:

<% Page Language="C#" Inherits="MyViewAtDesignTime" %>
...
<%=MyCoolHelper.CoolStuff() %>

You can mix that with the DictionaryAdapter integration:

<% Page Language="C#" Inherits="MyViewAtDesignTime<IPostView>" %>
... <%=MyCoolHelper.CoolStuff(view.Post.Title) %>

As usual: http://www.aspview.com

2007 Dec 4

AspView refactoring status

tagged as: castle | monorail | aspview

77 tests, all green.

That's all new tests from the last week.

I think it's almost stable enough for releasing it on aspview.com

I'll just put the old tests back in (with Ignore) as regression tests, until I'm comfortable enough to remove.

 

So - custom base classes for views are just around the corner.

Right after that - better extensibility (through custom Pre Compilation Steps provider and MarkupTransformation Provider)

 

you can of course watch the progress on svn (it's all on the trunk, so if you're using trunk for production, please restrain yourself a few more days ...)

 

stay tuned ...

2007 Nov 27

Using the CodeGenerator and the DictionaryAdapter

tagged as: tools | castle | monorail | aspview

Following users requests, I have just posted two documents to using.castleproject.org.

The first is an explanation about the CodeGenerator (from Contrib), and another one, on using the DictionaryAdapter.

Here are the links:

 

Related stuff:

2007 Nov 20

Screen Cast - Creating MonoRail-AspView Web Application From Scratch

Following many requests from users, I've created a screen cast in which I show how to setup a new MonoRail/AspView website, from scratch (no wizards).

CreatingMonoRailAspViewWebProjectFromScratchinVisualStudioExpress.wmv

On that demo, I've used Visual Web Developer 2008 Express and Visual C# 2008 Express, both in Beta2, just to show how you can simulate some of the "Web Application Project" experience in the Express editions. Of course it's much easier to work with a full Visual Studio with Web Application Project as you then have everything in a single application, and it's easier to handle.

Nothing on the demo is 2008 specific, and it runs on .NET 2.0, so VS2005 would do just fine here.

 

The demo is very simple, and I have generally just showed a "Hello World" level of setup. I hope to spare some time to follow up with setting up things like Windsor Integration, the Castle.Tools.CodeGenerator, and other cool stuff.

 

The links I use on the demo are:

I've used Windows Media Encoder to capture the screen, and my SHURE SM58 mic to record the narrating. It's a great mic, however plugged into my sorry excuse for a sound-card.

It's my first screen cast, and I'd love to hear comments from you people, both on the content and on the presentation.

2007 Nov 18

ActiveRecord.Linq - naive but Working

tagged as: c# | linq | castle | activerecord | nhibernate

I've spent some times lately with Linq To SQL and have played a bit with the Mapping namespace.

Why I do not like it very much is a matter for a different post. The matter at hand is that I want the power of Linq, and I want the power of NHibernate, and I want the easy road of ActiveRecord.

 

What do I mean by that? I'd like:

  1. query language == Linq
  2. persistence engine == NHibernate
  3. Mapping == ActiveRecord attributes

the needed prequisites:

  1. Linq (framework => framework.Version >= 3.5)
  2. NHibernate.Linq (source => source.getFrom(Rhino-Tools) )
  3. Linq for ActiveRecord - Keep on Reading

So, Ayende has kick-started it, and with some help from Bobby Diaz, we have a prototype level NHibernate provider for Linq.

To make it work with ActiveRecord, all you need is to add:

using System;
using Castle.ActiveRecord;
using Castle.ActiveRecord.Framework;
using NHibernate;
namespace NHibernate.Linq
{
public class ActiveRecordContext : NHibernateContext
    {
        public ActiveRecordContext() : base(null)
        {
            session = GetSession();
        } 
        private ISession GetSession()
        {
            ISessionScope scope = SessionScope.Current;
            if (scope == null)
                throw new InvalidOperationException("You should be in a SessionScope()");
            ISessionFactoryHolder holder = ActiveRecordMediator.GetSessionFactoryHolder();
            return holder.CreateSession(typeof(ActiveRecordBase));
        }
    }
}

and now you can do stuff like:

using (new SessionScope())
{
    ActiveRecordContext context = new ActiveRecordContext();
    var q =
            from c in context.Session.Linq<Category>()
            select c; 
    foreach (Category c in q)
        Console.WriteLine(c.Name);
}

Assuming Category has [ActiveRecord] mapping.

2007 Nov 13

ASP.NET MVC Framework - Demo App by Scott Guthrie

tagged as: castle | monorail | aspview

Scott Guthrie is going to present a demo application using the ASP.NET MVC Framework.

First episode is here: http://weblogs.asp.net/scottgu/archive/2007/11/13/asp-net-mvc-framework-part-1.aspx

 

Very interesting. I can already see four things that my current VS2005/MonoRail/AspView/IIS5-6 stack lack.

  1. I do not have a project template, so setting up a new project take a bit longer than clicking "new MVC project".
  2. I do not have default rewrite rules.
  3. I cannot use Server Controls.
  4. Web Designer support when doing views is not too good. Also, layouts are not treated as MasterPages by the IDE

Sounds bad?

Well:

  1. Since I am not at kinder garden, I do not "play" with setting up new projects. When I start a new project, it would probably last for quite some time. So the time it takes me to copy&paste a minimal web.config, setup a few lines in global.asax.cs, add references and create Controllers and Views folders, costs me about 5 minutes of the global project costs.
    I can live with that.
  2. Shame. However, I can add them to my initial web.config/global.asax.cs files that I use as templates for new projects. Again - one-time cost, and not a price-i one.
  3. I do not want to use those. Didn't use them even when I was doing WebForms. I'm happy enough with ViewComponents, SubViews and ViewFilters, and I can easily use any cool 3rd party JS controllers (YUI/Dojo/jQuery/ExtJs/Moo/You-Name-It)
  4. Again - I do not trust WYSIWYG generated markup. It might be good enough for the texts on my personal blog (dear Windows Live Writer - can't you <br /> instead of <br>? what's the deal). It is definitely not good enough for any production level web site.

So - all the downsides are taken care of.

 

Plus, the stack I use is being used in production environment by gazillion people (ok, AspView is not that common, but the ViewEngine is just 5% of the whole stack, and it's the rock solid part anyway). It is working with .NET 2.0 so I need not convince clients to go for installing .NET 3/3.5 on their shared hosting solution, and since it's open-source, I can tweak stuff for my needs without the need to wait for a hotfix/ServicePack that might never appear, if not too late.

 

And if I'm not enough of a jerk for ranting like that, I'm going to try (if I'd have enough time) to put up a sample application using MonoRail/AspView similar to Scott's, but this time, you would actually be able get the bits and run it on your machines.

 

Stay tuned.

2007 Nov 13

ViewFilter - Take 2

tagged as: castle | monorail | aspview

I've been asked lately about the use of the ViewFilter mechanism in AspView.

I've once written about it briefly here on my blog, and you can see it at http://www.kenegozi.com/Blog/2007/01/08/introducing-viewfilters.aspx

 

However, I'll post another (a bit more realistic) example here.

 

Scenario: some kind of a CMS thing. You want to present the user with some markup, in both "preview" mode and "Source" modes.

 

If the server had direct access to the markup in a string literal, things were easy. That usually happens when the markup is to be supplied by an end user, either directly or through a WYSIWYG Html editor. You'd end up with something like:

public interface IContentItem
{
    public string Markup { get; }
}

your view would look like:

...
<h3>Preview:</h3>
<div><%=view.ContentItem.Markup %> </div>




<h3>Source:</h3>
<div><%=Helpers.Html.HtmlEncode(view.ContentItem.Markup) %> </div>
...

 

easy enough.

 

However, what if the piece of markup that you want to show, has some view-logic, so you have a template generating the markup from an entity? For example, this blog has a view "Posts/One" that gets a Post entity, and fits it into a single post markup, putting the title in a <h4>, tags in <span> with theit title and href, etc.

How can you show the markup source for that?

ViewFilter to the rescue.

In short - A ViewFilter is a way to transform a chunk of a view, using simple manipulations. Do not look for that on other View Engines, as it's currently an AspView-only feature.

 

Let's code our needed filter:

 

public class HtmlEncodeViewFilter : IViewFilter
{
    public string ApplyOn(string input)
    {
        return HttpUtility.HtmlEncode(input);
    }
}

and in the view:

...
<% foreach (Post post in view.Posts)  { %>
<h3>Preview:</h3>
<subview:.Posts.One post="<%=post %>" > </subview:.Posts.One>

<h3>Source:</h3>
<filter:HtmlEncode>
    <subview:.Posts.One post="<%=post %>" > </subview:.Posts.One>
</filter:HtmlEncode>
<% } %>

 

Hey - you won't even need to create that filter. AspView is supplied with four basic (however useful) filters:

  • HtmlDecodeViewFilter
  • HtmlEncodeViewFilter
  • LowerCaseViewFilter
  • LowerCaseViewFilter

Can you think of more reusable view filters? why not post them here, or better yet, supply a patch to AspView with you filters?

2007 Nov 11

Nesting View Components in AspView

tagged as: castle | monorail | aspview

Following a request from Gauthier Segay, AspView now supports nested view components.

 

scenarion: you are using CaptureFor to inject markup from a view to a layout, and you want the injected markup to include a view component output.

 

in the layout:

...
<%=CapturedContent %>
...

 

in the view:

...
<component:CaptureFor id="CapturedContent">
   Some markup
   <component:SomeFancyStuff>Fancy component content</component:SomeFancyStuff>
</component:CaptureFor>

 

While working on that, I found out yet another problem. nested components of same type would brake

so:

<component:Bold><component:Bold>stuff</component:Bold></component:Bold>

would brake.

As you probably might know, the whole preprocessing of view, from AspView syntax to standard C# is done with Regular Expressions. For quickly doing the above, I helped myself to http://puzzleware.net/blogs/archive/2005/08/13/22.aspx in order to build the balanced tags aware regular expression, and now it works like a charm. Roy Osherove's Regulator was helpful, too.

 

So, as of revision 360 in Castle Contrib repository, nesting view components works (for both the trunk and the RC3 compatible branch)

 

As usual - go to http://www.aspview.com to get the binaries, or to http://svn.castleproject.org:8080/svn/castlecontrib/viewengines/aspview/ for the sources.

 

Cheers.

2007 Nov 8

AspView - AutoRecompilation mode is fully operational

tagged as: castle | monorail | aspview

If you set autoRecompilation="true" in your aspview section on web.config, then you need not use the vcompile.exe on every build. The views would get compiled in memory from sources.

Benefits: Change a view source, refresh the browser - viola, you can see he change impact. No need to rebuild the web project, the application is not restarted so no session is lost, and no need for "double refresh".

Still, when you deploy it's strongly advised that you'd run VCompile manually, copy the compiledViews.dll to the server, and set autoRecompilation="false" on the server's web.config.

 

The starter tutorial on using.castleproject.org is now updated, and you can download AspView binaries from http://www.aspview.com

 

Please use that (and other) new features and leave me some comments please ...

2007 Oct 29

AspView - New Syntax for Passing Parameters to SubViews (Breaking Change)

tagged as: castle | monorail | aspview

The old syntax for passing parameters to subviews was:

 

View sources files used to look like this:

<%Page Language= ... %>
... blah blah ...
<subview:whatever name="value"></subview:whatever>

 

The problem was that you could only have passed variables (by name), so if you needed to pass a string literal you had to declare a string object with the literal:

<%Page Language= ... %>
... blah blah ...
<%string value="literal"; %>
<subview:whatever name="value"></subview:whatever>

 

The new syntax follows the syntax for view components, and also the expected scripting syntax.

so now:

<%Page Language= ... %>
<%
%>
<subview:whatever name="mike" age="<%=30%>" currentItem="<%=item%>"></subview:whatever>

would pass the string literal "mike" to name, the int constant 30 to age, and the object item to currentItem.

 

You can download the new binaries, and a utility to migrate your existing views to the new syntax, from http://www.aspview.com

2007 Oct 29

AspView - New Syntax for Properties Section (Breaking Change)

tagged as: castle | monorail | aspview

So, what is Properties Section?

 

View sources files used to look like this:

<%Page Language= ... %>
<%
    int someProperty;
%>
... rest of view ...

 

The problem was that if you had no properties (or have used the DictionaryAdpater option described here) then you had to have an empty section, like:

<%Page Language= ... %>
<%
%>
... rest of view ...

 

Which is quite ugly.

 

So, following Lee Henson's suggestion, the properties section should now be wrapped in a special tag, and you can just omit that tag if you do not need to declare any properties.

The new syntax (new stuff in Bold Italic Font):

<%Page Language= ... %>
<aspView:properties>
<%
    int someProperty;
%>
</aspView:properties>
... rest of view ...

 

You can download the new binaries, and a utility to migrate your existing views to the new syntax, from http://www.aspview.com

2007 Oct 29

New Homepage for AspView

tagged as: castle | monorail | aspview

I've just setup a brand new site for AspView.

 

It's main purpose is to aggregate AspView related data to one central location. It would contain links to AspView related posts from this blog and others, links to online documentation and samples.

 

There'd be also a "download" page containing the latest builds to be used with Castle RC3 and Castle trunk.

 

The site's link is (surprise surprise): http://www.aspview.com

2007 Oct 25

I've just been Knighted as a member of the Castle

tagged as: castle

In one word: Wow.

 

In a few more: It seam that the Castle Project PMC got tired of me nagging them about some patches, so they've decided to make me a commiter.

 

Ken in Castle

 

I find it very flattering, as this group is made of very talented people, who are maintaining a rather large, sophisticated, extremely useful and widespread set of frameworks and libraries.

 

I hope I will stand up to the faith they've given in me, by contributing Good Stuff into the repository, and help making existing Good Stuff into Great stuff, and Great Stuff into Amazing.

2007 Oct 17

Typed View Properties in MonoRail and AspView

tagged as: asp.net 2.0 | c# | castle | monorail | aspview

Following my last post on the DictionaryAdapter, I'll demonstrate here how you can get typed access to your views' properties.

 

What it requires from you:

1. Declare an interface for each of your views. That is a Good Thing anyway, as designing to a contract is a good best practice, and it allows for easy testing.

2. Have a base class for your controller that would define TypedFlash and TypedPropertyBag. Not mandatory, but very convenient.

3. Use the newest build of AspView. Again - not mandatory, but helpful.

 

Now for the showtime.

First we would create a base class for our controllers, with a TypedPropertyBag and TypedFlash properties:

public abstract class Controller<IView> : SmartDispatcherControllerController
where IView : class
{
IDictionaryAdapterFactory dictionaryAdapterFactory;
    IView typedPropertyBag;
    IView typedFlash;
    protected IView TypedPropertyBag
    {
        get
{
if (typedPropertyBag == null)
        typedPropertyBag = dictionaryAdapterFactory.GetAdapter<IView>(PropertyBag);
return typedPropertyBag;
}
    }
    protected IView TypedFlash
    {
        get
{
if (typedFlash == null)
        typedFlash = dictionaryAdapterFactory.GetAdapter<IView>(Flash);
return typedFlash;
}
    }
    protected override void Initialize()
    {
        base.Initialize();
IDictionaryAdapterFactory dictionaryAdapterFactory = new DictionaryAdapterFactory();
    }
}

 

tip:

You can look at a more complete version of that base-class, written by Lee Henson (who have made some improvements to the original DictionaryAdapter, and also have introduced me to Peroni Beer).
The base controller also declares a type parameter for a Session DictionaryAdapter, hooks into the Castle.Tools.CodeGenerator, and uses IoC for DI.
Talking about those issues is a separate subject, for other posts.

 

Now let's create the view contract. A rather stupid example would be:

public interface IStupidView
{
    Guid Id { get; set; }
string Name { get; set; }
}

 

controller:

public class StupidController : Controller<IStupidView>
{
public void Index()
{
}


public void DoStuff(string name, string password)
{
if (password != "AspView Rocks")
{
TypedFlash.Name = name;
TypedFlash.Message =