Archive for the ‘Castle’ Category

Castle and .Net 3.5 SP 1

September 24th, 2008

Here are a few things I should clarify publicly regarding Castle and .Net 3.5 SP 1. First, the facts:

- The SP broke DynamicProxy 2 when creating a proxy for generic interfaces/methods (as Fabian described)
- The code that started to throw an exception is there to deal with a very edge case
- Breaking DynamicProxy breaks everyone that uses it (Rhino Mocks, Castle Windsor, NHibernate and Moq – those are the main ones I can think of now)
- I recently confirmed the problem and changed DynamicProxy code to not use those methods “r5323: Disabled the GetOptional/RequiredCustomModifiers calls so all tests (but one) pass”

So now everyone can continue to use DynamicProxy 2 and live happily. MS is going to make a fix available soon, according to scottha, so that we can re-enable that piece of code.

I don’t know, demographically speaking, the number of people affected by this. I do know and understand that publishing a SP that breaks something that was working make us look bad. That being said, I wish people could spend a day close to CLR team and be a fly on the wall on meetings and hallways discussions. Quality is serious business here.

Nothing is perfect, though, and some things slipped. At some point in time there wasn’t a test case for reflection emit that invoked GetOptional/RequiredCustomModifiers for generic interface/methods. Is that the end of the world? I don’t think so. And I’m sure they have one now.

Now, how could this be prevented? I have a dream.. If some team on CLR decided to run Castle tests cases with SP1, they would have detected that. Mono does aggregate external tests cases repositories to test their platform implementation. MS could do the same for a handful of OSS projects, where license is not a problem. If that’s not possible due to legal issues, the CLR team can streamline the communication with OSS teams and get early feedback. I have a dream… :-)

Categories: Castle, MS | Top Of Page | 7 Comments » |

Credits: be nice MVCContrib people

September 5th, 2008

I’m working on a prototype using ASP.Net MVC to build something that, well, will talk about some other day. Decided to use the MVCContrib to speed up some things (multiple view engines, ioc container integration). That’s cool. As always, the first thing I do is go through the code, testing the ground I’m stepping in, quality, design…

To my surprise I bump into things like IViewSourceLoader, IViewSource and FileSystemViewSourceLoader (namespace MvcContrib.ViewFactories). The same code (but with the license!) can be found here and here.

First this is a violation of ASL. Secondly, disregarding the legal blabber, have some common sense, kids. Give credits where it’s due!

Categories: Castle, OSS | Top Of Page | 11 Comments » |

Integrating MonoRail with your favorite IoC container

September 5th, 2008

I’m way outdated on my e-mail-reading and especially blog-reading. I don’t even read them anymore! I quickly scan them and try to get a gist… Someday people will actually emphasizes some words to make it easier for scanners like me to get the idea without stopping and reading every word ;-)

Anyway, I bumped into one of Jeremy’s post. Quoting:

“When we were deciding between Ruby on Rails, the ASP.Net MVC, and MonoRail for our project architecture in June, I dismissed MonoRail in small part because I didn’t want to be forced to use Windsor as our IoC tool (for some reason).”

Well, MR in no way forces you to use Windsor. For goodness’ sake, it’s on our mission page:

Castle should not be all-or-nothing. The developer can use the tools he wants to use, and at the same time, use different approaches in different areas of his application in a peaceful manner.

Of course, MR magically integrates with Windsor – what would you expect from us? But it can, just as well, magically integrates with any IoC container too.

So, what does it take to integrate MonoRail with your IoC container of choice?

First thing: MonoRail is made of several services. It had always used a composition-over-inheritance design principle that someone day more people will understand and adopt more – we’re always a decade behind, aren’t we?

(note to self: blog about all services that make the whole monster live).

So basically all you need to do is replace one or two services, depending on the level of integration you want. For the most basic integration, you might want to replace the controller factory and the filter factory by services implementation that know your IoC container (and knows how to access an instance of it). This can be made through the external monorail configuration (on the web.config) as described on the services article and on the configuration documentation.

A more complete level of integration, however, is something faily recent (10 months old I guess). Quoting an old post:

MonoRail now always uses the ServiceProviderLocator class to obtain a IServiceProvider and uses it as it’s parent container. That’s means that you can use any IoC container by simply making your HttpApplication class implement IServiceProvider (or better, IServiceProviderEx).

That means that MonoRail will always ask your code (the class that extends HttpApplication and is set on global.asax) before adding its default implementation of any of its services. That makes trivial to replace any service.

Note: I was actually going to provide a sample code but sorry, no time…

MonoRail marches into the cloud

September 1st, 2008

David is blogging about his experience with Amazon EC2. As you might know the images you can apply on a EC2 machine are all linux based. That didn’t stop him. He went on with Mono and MonoRail and got it working there. That certainly put more pressure on Castle community to get a bit more Mono-friendly/driven code. Now, if only the mono people could offer some help…

My first and last experience with EC2 was java based, and man, painful. The pain that only java can deliver. :-)

Seducted by the evil empire?

August 29th, 2008

So kevin states – leaving out the names – that a bunch of core .net talent is being hired by MS so the projects will eventually die, and that was the main MS goal. Ludicrous. The conspiracy theory keeps on and on.

I’d like to offer another perspective, from someone deeply involved with OSS since 2002. It’s not easy to have a regular job and dedicate a chunk of spare time to create code and have absolutely no financial compensation. Ok, it’s your decision, you’re passionate about it. I know I am. I had a java full time job and spent evenings and weekends creating and trashing IoC container code in .net in my quest for an extensible design. Eventually that lead to Windsor and the MicroKernel.

In October 2006 I dared to start a company completely related to Castle, offering training, consultancy and development. Do you think I got rich? Do you think I made enough money to keep me going? Think twice.

The company is well now, but that’s more due to a shift to the financial market and products than anything else. We were getting gigs due to our speed and quality, and our clients didn’t give a s… what we were using to get it done. Castle, and any other OSS involvement, would only lead me to the path of starvation. That’s why I completely sympathize with Zed Shaw’s Rails is a Ghetto rant. People want too much: they want bugless code, they want perfect documentation, and yet they don’t want to pay a penny for any of that, nor contribute.

That’s not only on .net by the way, that’s a general developer’s position on libraries/frameworks. There are two possible escapes: if you focus on the mid tier and talk directly to CTOs (like JBoss and MySql do), or you focus on productivity tools (like JetBrain does). Otherwise, you’re doomed.

Lutz decided to sell Reflector. Man, I couldn’t be happier for him. Imagine the countless nights and weekends he had spent on that. After eight years he got some compensation. And that’s unfair? If you think so, try to live from OSS and let me know in an year or two if you have the same opinion.

Categories: Castle, OSS | Top Of Page | 6 Comments » |

Poor man’s usability test

July 3rd, 2008

Going public with donjon was a great decision. We got several levels of feedback, and not all of them are conscious or direct. Let me go over some of these:

Exceptions

First of all, we use MonoRail Exception Chaining extension and get e-mail with all exception details, plus the page, form, query string, session and flash state, so it’s relatively easy figuring out how to reproduce the situation that caused the exception. This approach wont send us only unhandled exceptions, instead we use RegisterExceptionAndNotifyExtensions to make sure we get it. The following is a typical donjon’s action in a controller

[return: JSONReturnBinder(Properties = "Id,UserName,FullName,Email")]
[AccessibleThrough(Verb.Post)]
public User[] AddMembers(string key, string[] users)
{
    try
    {
        ...
    }
    catch(Exception e)
    {
        RegisterExceptionAndNotifyExtensions(e);
        Logger.Error("AddMembers failed", e);
        throw;
    }
}

RegisterExceptionAndNotifyExtensions will make sure the chain is going to be executed. The Logger is our ultimate place to detect problems, finally we throw so the ajax call get a status 500. Some places I dont even throw, just set StatusCode to 500 and RenderText(a nice error message)

I also find a best practice to always start writing and testing an action/page with the error handler. So my actions usually starts as this:

public void Action()
{
    try
    {
        throw new Exception("something bad");
    }
    catch(Exception e)
    {
        RegisterExceptionAndNotifyExtensions(e);
    }
}

I find a good practice to assume that at some point something might go wrong, and the user is properly notified. It’s just too much to assume that the action will always be successful.

Settings and defaults

Each user on donjon has a preferences setting. Inspecting the database I found that almost no one ever set a preference. Disturbing to me, as I think the Issue list as it is is just too bloated with information, so the first thing I do is configuring it to show less columns. Nobody did that, possibly because nobody knew how to do it.

Ok, lesson learned and code fixed. donjon will set up an user with an initial preference set to less columns.

Right side Navigation

Aaron complained about this one. It was inspired on some tool I’ve used, so I thought breaking the convention would be a good thing. Bad news to me: “don’t break user expectation” and “don’t try to create new conventions unless they are revolutionary” are some huge bullet points in the book “Prioritizing Web Usability”.

Just to unarguably prove that my decision was dumb, I found the article Navigation: Left is Best

Another lesson learned.

Others

The issue list page was designed and redesigned at least 10 times. All of them functional. The present version is the one that I’m satisfied, but I’m sure there are room for improvements.

I gotta tell you that at first it’s not easy to not to think as a programmer and instead wear the user hat when designing a page. Your programmer’s mind want to make things easier for you (code-wise), your user’s mind wants to make things much more complex. Yeah, sometimes to make the experience simpler you have to write much more code. My guess is that it’s an eternal struggle.

So expect some big improvements for beta 2 :-)

CombineJS ViewComponent

June 27th, 2008

A while ago I added this issue, which is basically a spec for a viewcomponent I urged for, in the hope that someone would face the challenge and, well, just do it. My first thought was that creating something like that would be a bit complex. Here’s the issue description:

The idea is to be able to combine and allow browsers to cache a set of files:

#blockcomponent(JSCombine)
$combiner.add("$siteroot/content/jquery-1.2.3.js")
$combiner.add("$siteroot/content/jquery-someplug.js")
$combiner.add("$siteroot/content/myjs.js")
#end

Which should output something like

59e89c82402501_

The hascode should be a composition of the lastmodified of each file's lastmodified attribute, so if a file is changed, the browser will request them again.

There should also be a CssCombine.

The goal is pretty simple: one request and all js is downloaded, hopefully cached, and if some file change a new hash will force the browsers to update their copy.

Today I decided to go on and implement that, was prepared to spend the whole day, but dont know how, was done in less than an hour.

Here the idea:

  1. Collect a list of the files
  2. Calculate a hash based on the last modified date of each file
  3. Create an in-memory aggregation of all files
  4. Register this content within MonoRail static resource service
  5. Output a script tag pointing to the newly created MR resource

And here’s the code that does exactly that:

[ViewComponentDetails("CombineJS")]
public class CombineJSViewComponent : ViewComponent
{
    public override void Render()
    {
        var combiner = new CombinerConfig(AppDomain.CurrentDomain.BaseDirectory);
        PropertyBag["combiner"] = combiner;

        // Evaluate the component body, without output 
        RenderBody(new StringWriter());

        string key = (string) ComponentParams["key"];
        long hash = CalculateChangeSetHash(combiner.Files);

        IStaticResourceRegistry resourceRegistry = EngineContext.Services.StaticResourceRegistry;

        if (!resourceRegistry.Exists(key, null, hash.ToString()))
        {
            var staticContentResource = 
                new StaticContentResource(CombineJSContent(combiner.Files));

            resourceRegistry.RegisterCustomResource(
                key, null, hash.ToString(), staticContentResource, 
                    "application/x-javascript", DateTime.Now);
        }

        string fullName = "/MonoRail/Files/CombinedJS?name=" + key + "&version=" + hash;
        RenderText("<script type=\"text/javascript\" src=\"" + fullName + "\"></script>");
    }

    private string CombineJSContent(IList<string> files)
    {
        StringBuilder sb = new StringBuilder(1024 * files.Count);

        foreach(var file in files)
        {
            using(StreamReader reader = File.OpenText(file))
            {
                sb.Append(reader.ReadToEnd());
            }
            sb.AppendLine();
        }

        return sb.ToString();
    }

    private static long CalculateChangeSetHash(IList<string> files)
    {
        long hash = 0;

        foreach(var file in files)
        {
            if (File.Exists(file))
            {
                DateTime dt = File.GetLastWriteTimeUtc(file);
                hash += dt.Ticks * 37;
            }
        }

        return hash;
    }

    public class CombinerConfig
    {
        private readonly string basePath;
        private readonly List<string> files = new List<string>();

        public CombinerConfig(string basePath)
        {
            this.basePath = basePath;
        }

        public IList<string> Files
        {
            get { return files; }
        }

        public void Add(string jsFile)
        {
            Add(jsFile, null);
        }

        public void Add(string jsFile, IDictionary options)
        {
            files.Add(Path.Combine(basePath, jsFile));
        }
    }
}

And this is how to use it (Nvelocity view engine example)

#blockcomponent(CombineJS with "key=deflayout")
 $combiner.Add("Content/js/jquery/jquery-1.2.6.min.js")
 $combiner.Add("Content/js/jquery/jquery.metadata.js")
 $combiner.Add("Content/js/jquery/jquery.label_over.js")
#end

Note that the key must represent an unique set of files.

Now my plan is to add js minify capabilities, either by selecting the minified file using a naming pattern, or minifying in place.

Some clarifications regarding JetBrains partnership

June 22nd, 2008

I’m getting lots of e-mails asking for discounts, but the thing is: the discount is for Stronghold’s clients. I may open exception for volume purchases only.

Using Castle does not qualify you as a Stronghold client, after all, have you paid any license fee to use Castle?

Thanks for understanding

Session on ajax apps with MonoRail

June 9th, 2008

Skillsmatter is promoting another Castle related session, presented by Gojko Adzic and David De Florinier.

http://skillsmatter.com/…/developing-ajax-web-applications-with-castle-monorail

This is the kind of event I like to participate anonymously and ask tough questions ;-)

Categories: Castle | Top Of Page | 1 Comment » |

Where no man has gone before

June 6th, 2008

Bill seems to have guts. He has posted some of his experience with a custom MonoRail + Windsor solution for a b2b app, and seems to have gone deep to customize the way components are resolved to address a business requirement. His point: majority of his clients deal with orders their own way, instead of branching the code or scattering ifs everywhere, he creates a customized component that deal with those requirement, which is automatically selected based on the client accessing the app.

To have that working, he decided to go down and speak with the devil himself. He embraced the use of containers hierarchy.

First of all a disclaimer: the support for parent/child container was added long time ago to MicroKernel/Windsor, really long time, probably in the first commits. But they never went into a _real_ real world testing. Also, I’m not sure the dependency resolution behavior is safe enough. I implemented support for one-way, bottom-up resolution to prevent someone from doing something really bad, but I’m not sure that’s enough. For all these reasons – plus a gut feeling that I shouldn’t have added this concept in the first place – I strongly discourage its use. And that’s why there are no documentation about it on castle web site, no articles (from me at least), and probably no blog posts.

Now if you like sky skiing, drives a motorcycle without helmet, have a compelling reason to use it, then why not give it a try? :-) Bill knows what he’s doing, though, he has contributed patches that demonstrates a deep understanding of the inner workings of castle.

Another idea that I played for a while was the concept of scoped containers for web apps. Mapping containers to the life styles associated with a web app: application, session, request. That would make simple to have components to lifestyles attached to an user session, for instance. However it’s a lot of work and difficult to test. I’m sure it will be available on Windsor/MonoRail 2.0