Omer Van Kloeten has initiated (with Ayende) an Israeli Bloggers Dinner.
If you're intersted, leave a comment on his post.
A nice page made available by NASA is showing an astronomy related picture each day.
I liked today's and yesterday's pictures a lot.
Here is a warning that IE7 poped up on me on hattrick:
This website wants to run the following add-on 'MSXML 5.0' from 'Microsoft Corporation (unverified publisher)' ...
huh?
Ayende has posted about the matter, only he've used the title "MonoRail vs. ASP.NET" instead. I think that his title isn't accurate since MonoRail is actually a WebForms replacement that is built ontop of ASP.NET, exploiting all of the cool features found in ASP.NET and in the .NET framework alltogether. It's the Web development framework that Microsoft forgot. So it has the benefits of the Rails interpretaion for MVC, with the power of .NET.
Here is the comment I've posted to Ayende's post:
"My point of argue in favor of MR for people who are afraid of "non-microsoft" is, that actually MR is ASP.NET. It is just not WebForms.
You get all the good stuff from ASP.NET: the .NET framework for start, compiled views (on Brail - kudos to you), the HttpModule stuff, seeamless integration with AR.
This is what I say to the PMs, etc.
To the developers themselves who are afraid, There's a more detailed approach.
Developers (especially ones who didn't do web programming aside ASP.NET, and probably has a lot of VB experience but no PHP/JSP/ASP) like WebForms cuz they can get to the txtUsername.Text, txtPassword.Text, and txtAge.Text easily, not needing Request.Form["Password"] (hey - it's not typed !!!) . But then I reffer them to the fact that actually txtAge.Text isn't typed too. it's a string, and should be parsed, tried, validated etc.
They should also manually create a User instance, and fill it's properties.
Doing the same on MR with Dispatching and AR is there without any line of code. I show them an example aqnd then hold them as they almost fall off their chairs.
Not'n like a good example.
Maybe having a ViewEngine that's use c# or VB.NET instead of boo (not the WebForm ViewEngine which suck, but somthing similar to Brail) can make the move from WebForms to easier for developers, but frankly, as you've said, people who can't get it OJT with a few examples aren't the one's I'm likely to work with anyway."
For all of you HDTV / 10MegaPixel Cameras / 22" 5000X4000 screens - you should read this about the human eye's resolution
It relates nicely to the single pixel camera thingie.
As said in the title, ASP.NET Ajax (aka ATLAS) is maturing and reached Beta 1 stage.
I haven't being too mush into it lately, since I've been under the impression that though Microsoft's ASP.NET Ajax library was very rich and had many features, it also suffered from many childhood problems, including too many js errors, and a huge .js script to download.
Now, it has an official name, and a beta release, and it's maturing. The .js was split by functionality, release and debug version of the .js are present, prototyped classes have replaced the closure based ones, and it's better for me cuz I find it easier to *overload* behaviuors when needed.
So try it out and read what Scott Guthrie has to say about it.
Since nowadays I'm more into MonoRail over Brail than into Webforms, I guess that the Core package is what really intresting for me, and I'll try to combine it with AjaxHelper from MonoRail. I hope to report on the matter shotrly.
Scott Guthrie has posted about the new CTP of the VS for DB Profs. I haven't used this tool until now, but it looks as if I'm going to ... I was looking for a better and easier solution for keeping an eye over the changes of DB schemas in projects I'm involved with, and I'm definitly going to check this one out.
On a small debate with a friend, about weather he should design and implement a Data Access Layer himself, or use an existing framework, I came across a piece by Ayende about 25 Reasons Not To Write Your Own Object Relational Mapper.
I'd like to add a quote from Code Complete 2 about programmers who are reluctant to read (and use) existing solutions to known problems (on p. 823):
... even if you want to reinvent the wheel, you can't count on success. You might reinvent the square instead.
It's definitely not a Dave Barry kinda funny punch line, however it's very much to-the-point.
There are many methods to query your data when you're on Castle's ActiveRecord.
Thanks to Ayende, we have a new cool way of doing that, namely NHibernate Query Generator 1.5.
1. You can skip querying, fetch everything and check it in the client:
1: Blog[] blogs = Blog.FindAll();2: foreach (Blog blog in blogs)
3: {4: if (blog.Name== "Cool Blog")
5: { 6: firstPostTitleName = blog.Posts[0];7: break;
8: } 9: }The Good: Type safety - can catch a lot of errors in compile time
The Bad: One should let the DBMS handle queries. It's a total waste of resources.
The Bottom line: AVOID
2. You can use direct SQL:
1: string firstPostTitleName = (string)ActiveRecordMediator.ExecuteQuery(
2: new ScalarQuery(typeof(string), QueryLanguage.Sql, @"
3: SELECT TOP 1 Title 4: FROM Post INNER JOIN Blog ON Post.BlogId=Blog.Id5: WHERE Blog.Name= ""Cool Blog"""));
The Good: Well, it'd probably work.
The Bad: Joins? Blog.Id? hey - I thought we are using an OR/M !! plus it's not type safe,
The Bottom line: AVOID AT AL COST
3. You can use HQL:
1: string firstPostTitleName = (string)ActiveRecordMediator.ExecuteQuery(
2: new ScalarQuery(typeof(string), @"
3: select title 4: from Post p5: where p.Blog.Name = ""Cool Blog"""));
6: The Good: Working with objects, nice and readable query string.
The Bad: not type safe,
The Bottom line: Use only when 4 and 5 are not applicable.
4. You can use ICriteria:
1: string firstPostTitleName = Post.FindOne(
2: Expression.Eq("Blog.Name", "Cool Blog"));
The Good: Working with objects, less strings means less error prone.
The Bad: not type safe, and a little less readable than HQL
The Bottom line: Use only when 5 is not applicable.
5. And now you can use NQG:
1: string firstPostTitleName = Post.FindOne(
2: Where.Post.Blog.Name == "Cool Blog");
The Good: Readable, type safe.
The Bad: I do not how to invoke sql server side functions with that. And it is a little premature, so you should have solid tests. But you should have them anyway.
The Bottom line: Prefer using this method. If it fails, go to 4 or 3.
So IMHO it is a great tool, and I've went right away to test it and play a little with the source (I've even found and fixed a little bug !!).
Notice that I've tagged it under Linq, too, since it gives us a Linq-ish way to query the DB in a typesafe elegant manner. In VB.NET the query code looks even better.
I am working with AR for a few month now, ignorantly ignoring the Castle Project's wiki.
Stupid I am. I could have learned a lot and save a bunch of wandering around the net and the intellisense to learn obvious stuff.
Thanks to hammett who pointed me there.
Anyway - now I read it from <html> to </html>, and I saw the part about running HQL using the Execute Callback
There are examples, each one with two flavors: "not using generics", and "using generics". Well, the one about the Execute Callback is misleading. It should have been "not using anonymous method" and "using anonymous methods", since the second one does not use generics.
So I thought - let's make the API simpler.
We would have like to allow the user execute her hql like that:
1: public static Post[] GetPostsByAuthorName(string authorName)
2: {3: return (Post[])Execute(typeof(Post), "from Post p where p.Author = ?", authorName);
4: }Or even better, by using generics (this time for real):
1: public static Post[] GetPostsByAuthorName(string authorName)
2: {3: return Execute<Post>("from Post p where p.Author = ?", authorName);
4: }Here is the magic:
1: public static T[] Execute<T>(string hql, params object[] parameters)
2: {3: IList untypedResults = (IList)Execute(delegate(ISession session, object data)
4: {5: object[] queryParams = (object[])data;
6: IQuery query = session.CreateQuery(hql);7: for (int position = 0; position < queryParams.Length; ++position)
8: query.SetParameter(position, queryParams[position]);9: return query.List();
10: }, parameters);11: T[] results = new T[untypedResults.Count];
12: untypedResults.CopyTo(results, 0);13: return results;
14: }I'll add an overload that will accept named parameters. I am not sure about the right way to do that, though.
My options are:
1: Execute<T>(string hql,
2: string[] paramNames,
3: Type[] paramTypes, 4: object[] parameters)
Or:
1: Execute<T>(string hql, IParameter[] parameters)
where IParameter definition is something like:
1: public interface IParameter<T>
2: where T: Type
3: {4: public string Name { get; set;}
5: public T Value { get; set;}
6: }Maybe both?
And maybe I haven't read the wiki thoroughly enough and there are already implementations for all that?
Brad Abrams has published on his blog a short presentation about 5 rules for good framework design, a presentation he is giving at the Pattern and Practices Summit event.
The stuff there is taken the "Framework Design Guidelines" book, written by Brad and Krzysztof Cwalina. I'd recommend to people who develop frameworks for the use of other developers, to get acquainted with the ideas, and also read the book (from constructor to destructor), possibly leaving it on their shelf for future reference.
The presentation itself is very good in it's design - large and readable text (though slide 4 is of balance - maybe he's relying on a non-standard font). the pictures and examples are funny and to-the-point, and it has meaningful colors (as if Do Not needs a red X nearby ...). The story on slides 12 to 26 is cute, and you get the message simply enough.
I'd add to the StopWatch example from slide 7, the method .Restart(), if I'd want the user to have even a simpler way to reuse the object.
WARNING:
I'm going to use some lousy examples in this post. Please bear with me, and stick to the Point rather than to the actual Classes being presented.
What is a projection?
Consider this genius ERD:
A sample projection could be a kind of a view:
The SQL is (surprise!)
1: SELECT2: p.Title as PostTitle, c.Content
3: FROM 4: Comments c INNER JOIN 5: Posts p ON c.PostId = p.IdBut we live in the Classes/Code/Compiler/Types/etc. domain, not the SQL domain, so I'd need a Post and a Comment classes that would derive from ActiveRecordBase<>.
But what about the CommentsView?
I can select into an array of objects using a simple HQL's select:
1: IActiveRecordQuery query = new HqlBasedQuery(typeof(Job),
2: "select c.Post.Title, c.Content from Comment as c");
3: 4: ArrayList report = ActiveRecordMediator.ExecuteQuery(query) as ArrayList;
But I do not want to, since every item in the ArrayList is of type object[]. yuck.
No, I want to use a CommentView class, and this syntax:
1: IActiveRecordQuery query = new HqlBasedQuery(typeof(Job),
2: "select new CommentView(c.Post.Title, c.Content) from Comment as c");
3: 4: ArrayList report = ActiveRecordMediator.ExecuteQuery(query) as ArrayList;
and now the ArrayList contains CommentView objects.
In order to achieve that, we need to use the peculiar named attribute, [Import] like that:
1: [Import(typeof(CommentView), "CommentView")]
2: [ActiveRecord("Comments")]
3: public class Comment : ActiveRecordBase<Comment> { /* blah blah */ }
Now ActiveRecord (assuming Comment class was initialized using ActiveRecordStarter) knows that CommentView refers to a projection of the Comment ActiveRecord, using the class CommentView.
The use of [Import] is not documented too well, so I've included ImportAttribute in the post's title so It could be easily found. After a few refinements I hope to post it to the CastleProject wiki.
Note Ayende's post, with some better example for projection, but it lacks the demonstration of using Import attribute, so that's actually the reason for this post.
That's for the "how you do that".
now for the "How I think you should be able to do that":
well, INHO, the Import attribute is poorly named.
The name of the Attribute makes no sense to me.
The lack of default name makes no sense to me. I should be able to
1: [Import(typeof(CommentView))]
And what if I need some different projections to the same AR type? Multiple Import attributes make no sense, too.
Does the Import attribute serves a different purpose? If not – why not call it “Projects”? (since it projects to some other classes)
like:
1: [Projects(typeof(CommentProjectionOrWhatever))]
2: public class Comment : ActiveRecordBase<Comment> { /* blah blah*/ }
or even better yet:
1: [Projects(2: typeof(CommentProjectionOrWhatever),
3: typeof(YetAnotherCommentProjectionNeededForDemonstrationPurposesOnly )]
PROBLEM:
When editing Monorail views, you are losing the XHTML intellisense that normal webforms have in Visual Studio.
SOLUTION:
Add a proper xmlns to the html tag.
My layouts start with this:
1: <?brail 2: output '<'
3: output '?xml version="1.0" encoding="utf-8"?'
4: output '>'
5: ?>6: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
7: <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="he-il" lang="he" >
This applies to brail, but can of course be used on any other view engine, with the needed adjustments.
Lines 1-5 is needed due to a bug(?) in some versions of brail. brail used to recognize a script by '<? ?>', '<?brail ?>' and '<% %>' signs. therefore, using a <?xml ?> declaration caused the boo compiler to say that he knows nothing about 'xml'. I think that Ayende has solved the problem now, by allowing only '<?brail ?>', but I think it's not yet on the main trunk, so I still use the listed method.
Line 6 is the DOCTYPE, I use XHTML 1.0 transitional.
Line 7 is the magic part. Visual Studio parses this line, reads the xmlns, and can hint you with intellisense for html tags and attributes. The xml:lang and lang attributes are of course changeable.
It works in layouts, or in views that are a full html document (with <html> tag) but not with VieComponents or views that uses layouts.
If someone has a way to do that, please share it.
I've been on a trip to Rhodes for the last few days, so no progress on Monorail or any other technical stuff was happening, but I do have a few pictures to share. It would take some time to post, since I have some projects that needs some working on, but eventually you'll be able to see the great pictures (taken on my lousy nokia phone's camera) and read some (not so funny) stories.