Model Attacher pattern in Silverlight applications
A while ago, when we started to develop our next version of RavenDB Studio, one of our goals was to make its code as simple as possible. That way, we ensure that it is easy to understand what is going on, so making changes to the Studio should be a trivial task.
In order to achieve that, we decided to not use any MVVM toolkits, but simply use a simple pages (views) and attach a model to them. In this approach, every view (page) know how to resolve its view-model by itself. This makes the Silverlight code much more simple, since it let’s you open a specific view by just navigating to its relative URL.
In order to make this possible we have a ModelAttacher.AttachModel attached property on the page, which takes care of instantiating the view-model and attach it to the page’s DataContext property.
Take a look on the following tipical view (page) in order to see it in action:
<Infrastructure:View x:Class="Raven.Studio.Views.Home" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:Infrastructure="clr-namespace:Raven.Studio.Infrastructure" Title="Home" Style="{StaticResource PageStyle}" Infrastructure:ModelAttacher.AttachModel="HomeModel"> </Infrastructure:View>
In this example, we have an empty Home view, which is make a use of a HomeModel. The ModelAttacher’s job here is to create an instance of the HomeModel class and attach it to the View.DataContext property. (The view is a simple class that derives from Page.)
This is how ModelAttacher works, in order to achieve this:
namespace Raven.Studio.Infrastructure { public static class ModelAttacher { public static readonly DependencyProperty AttachModelProperty = DependencyProperty.RegisterAttached("AttachModel", typeof(string), typeof(ModelAttacher), new PropertyMetadata(null, AttachModelCallback)); private static void AttachModelCallback(DependencyObject source, DependencyPropertyChangedEventArgs args) { var typeName = args.NewValue as string; var view = source as FrameworkElement; if (typeName == null || view == null) return; var modelType = Type.GetType("Raven.Studio.Models." + typeName) ?? Type.GetType(typeName); if (modelType == null) return; try { var model = Activator.CreateInstance(modelType); view.DataContext = model; } catch (Exception ex) { throw new InvalidOperationException(string.Format("Cannot create instance of model type: {0}", modelType), ex); } } public static string GetAttachModel(UIElement element) { return (string)element.GetValue(AttachModelProperty); } public static void SetAttachModel(UIElement element, string value) { element.SetValue(AttachModelProperty, value); } } }
Now in order to attach a model to its view, we need to just add the attached property to the view element: Infrastructure:ModelAttacher.AttachModel="HomeModel".
Please note that in this case any view-model has to have a default (parameters-less) constructor. In order to solve that, what we have done in RavenDB Studio is to have a ModelBase class for our view-models which make sure to expose all our common model dependencies.
XAML Magic: Turning an Ugly Silverlight Duckling into a Beautiful Photoshopped Swan
This is a guest post by Samuel Jack, who had done a lot of work on the new UI for RavenDB.
Three weeks ago Ayende put out a request for help in turning an ugly duckling into a beautiful swan, and I, rather nervously, signed up for the job. The ugly duckling in question was Raven Studio, the Silverlight-based management UI for Raven Db. The nerves were a result of doubting that my limited graphic design skills were up to the job. But when Ayende assured me that he had a proto-type swan in the form of a Photoshop design, drawn up by a bona-fide, turtle-neck-wearing designer, they were calmed. Marginally.
Because the design Ayende had was for the new-look RavenDb website.
He wanted me to take the look and feel and transfer it to the Silverlight Raven Studio application. Which, when he handed it over to me, looked like this:
Ahh! Where to start?
Photoshop for Developer Dummies
To ease myself in, I got started by simply trying to imitate parts of the Photoshop design in XAML, beginning with the header bar at the very top of the page. Not being a designer myself, I’m rather like a duck out of water when it comes to Photoshop, but I’ve at least got the basics sussed.
The thing to understand is that designers construct Photoshop images like onions, layer upon layer, sometimes eye-watering in complexity, and to reproduce the design, you have to peel down through the layers.
First go to Photoshop’s Layers pane, and make sure all the layers are unlocked. This allows the Move Layer tool to come into play, not to move layers, but identify layers by selecting them in the Layers pane when you click the corresponding part of the image. Once you’ve identified a layer, Alt-Click it, and all other layers in the image will be hidden, allowing you to figure out exactly how the thing should look.
Mostly when I’m paring down Photoshop layers I’m looking to isolate them so that I can figure out the colour gradients they use. You could, of course, navigate your way through Photoshop’s dialogs to read off the exact RGB values. Or, if you can get the layer on its lonesome, you can use Expression Blend’s Gradient Dropper tool. ![]()
This is a brilliant little timesaver. In the Blend Property pane, select the Brush property of your choice, put it into Gradient mode, click the Gradient Dropper tool, then drag over any area on screen, and Blend will reproduce the gradient under the cursor in XAML form.
After all that, I have the first feather of the new swan: a header bar matching the Photoshop design. Well, the background of the header bar. It needs fleshing out with some buttons.
Let it Live: Control Templates and Visual States
Silverlight, following WPF, has the concept of look-less controls. That is, the Controls (take Button as an example) manage their behaviour (Buttons respond to mouse clicks by executing commands) but don’t define how they are rendered on screen. That is left to the control’s Style, and specifically its ControlTemplate. The ControlTemplate defines the visual tree of all the UI elements needed to present the control and make it look snazzy. With a little patience, some assistance from Expression Blend, and plenty of application of the Gradient Dropper tool, it’s possible to take the built-in controls and make them look and feel just how the designer ordered.
I wanted Buttons that look like those in the header bar of the Photoshop design, but when the corresponding page is selected, they should change to have a background gradient with colours like the RavenDb logo.
When restyling a Control, it’s best to start by modifying the existing style. This way you can be sure you won’t miss an aspect of the control’s behaviour that you might otherwise forget. Blend makes this easy by giving you the option of editing a copy of the Control’s current ControlTemplate (right-click on it in the Objects and Timeline View, then select Edit Template > Edit a Copy). There are occasions when that little trick has failed, and I’ve ended up with an empty control template. But MSDN has come through for me then: it has a whole section containing the default Styles and Control Templates for all the built-in controls, like this one for Button.
Part of the ControlTemplate defines how the control looks in its various states, when the mouse is over it, when it has focus, or when it is selected, for example. The Control itself is responsible for indicating when it has entered each state. As a designer, it’s your job to specify Storyboards that are activated each time particular states are entered. Each Storyboard can animate whichever properties it likes to achieve the desired effect – in my Buttons, for example, I animate the opacity property of a Border element to fade in a coloured background indicating that it is selected. All this is overseen by the VisualStateManager, of which, more here. Naturally, Expression Blend has great editing support for visual states. Read John Papa’s tutorial to learn more.
So now I have a header bar with buttons that change colour when the corresponding page is selected. Where next?
Textured Backgrounds
Well, that page background could do with spicing up. The Photoshop design has a nice textured background, which I extracted to a PNG file that Silverlight would understand by hiding every layer except the background, then using Photoshop’s “Save for Web & Devices” feature.
The thing about textured backgrounds is that you do want them to cover the whole of the page background, which means tiling the texture to fill all the space. WPF makes this easy with its ImageBrush, which has a TileMode property, which, when set to a value other than None, automatically repeats the image over the whole area to be painted by the brush. Silverlight has ImageBrushes, but they don’t support tiling out of the box. Fortunately, Phil Middlemiss has supplied what is lacking in the form of the TiledBGControl which does exactly what I need – you should take a look: it makes clever use of Silverlight’s pixel shader effects.
This is what we’ve got so far.
The Index Editor Page, Before and After
Here are a couple of other pages I’ve beautified. First, the Index Editor page, as it was before:
And now:
Again, it was a challenge knowing where to apply my beautician’s brush first. I settled on adding the header bar at the top, and I then realised it could double up as a toolbar. Originally the page had no header at all, but by having a bread-crumb bar in the header it helps to give the user a bit more context when they’re looking at the page, as well as making it easier to navigate around.
Inspiration and Icons
Since my graphic-design skills are so underdeveloped, I borrow ideas shamelessly wherever I find something that fits. You may recognise the styling of the toolbar buttons in the Index page header bar as being remarkably similar to the ones on the Google Chrome toolbar. Yes – Expression Blend’s Gradient dropper does work on live applications too! Two places to check out if you find yourself short on inspiration are Quince and Pattern Tab which both catalogue examples of user interface and user experience design from across the web. Pattern Tab especially has myriad examples of beautiful UIs.
In the past I’ve struggled to find icons for my projects, but I’ve recently discovered two great sources: IconFinder.com and IconArchive.com. Both have excellent search facilities (which is often what’s missing from the commercial collections you buy and download to your machine in a whacking great zip file), and are careful to call out the license attached to each icon. A surprisingly large number are licensed so that they can be used without charge in commercial products.
A XAML Tip
The nice thing about styling an application is that it gets easier with every page you complete. Once you’ve settled on a look for a particular kind of element, you can repeat that look on every page. Silverlight’s support for Styles and Resources makes this very easy. And I have a tip that can make it easier still.
I put all my styles into a single resource dictionary, Styles.xaml which I merge into my App.xaml resource dictionary. I then name all my Styles, Brushes, etc. using a hierarchical naming convention. So Styles all begin with “Style_”, Styles for Buttons would all begin “Style_Button”, and then would come the styles for different purposes: “Style_Button_Toolbar”, “Style_Button_Hero” (for those big red buttons in your app that the hero uses to save the world), etc.. The pay-off for using this convention comes when you’re hand-editing XAML and making use of Resharper’s XAML intellisense. Type “{StaticResource Style_[ControlType]” and Resharper instantly presents you with a list of all the styles that might apply.
A Parting Screenshot
To finish, here’s one more before and after comparison, this time of the Edit Document page. Before:
And after:
You can begin to sense the benefit of using a consistent set of styles, as it brings a harmonious feel to the whole application.
I hope you’ve enjoyed this whistle-stop tour of the Raven Studio beautification process. Remember that all the code is available on GitHub. We’d love to hear what you think.
XAML Magic: Turning an Ugly Silverlight Duckling into a Beautiful Photoshopped Swan
This is a guest post by Samuel Jack, who had done a lot of work on the new UI for RavenDB.
Three weeks ago Ayende put out a request for help in turning an ugly duckling into a beautiful swan, and I, rather nervously, signed up for the job. The ugly duckling in question was Raven Studio, the Silverlight-based management UI for Raven Db. The nerves were a result of doubting that my limited graphic design skills were up to the job. But when Ayende assured me that he had a proto-type swan in the form of a Photoshop design, drawn up by a bona-fide, turtle-neck-wearing designer, they were calmed. Marginally.
Because the design Ayende had was for the new-look RavenDb website.
He wanted me to take the look and feel and transfer it to the Silverlight Raven Studio application. Which, when he handed it over to me, looked like this:
Ahh! Where to start?
Photoshop for Developer Dummies
To ease myself in, I got started by simply trying to imitate parts of the Photoshop design in XAML, beginning with the header bar at the very top of the page. Not being a designer myself, I’m rather like a duck out of water when it comes to Photoshop, but I’ve at least got the basics sussed.
The thing to understand is that designers construct Photoshop images like onions, layer upon layer, sometimes eye-watering in complexity, and to reproduce the design, you have to peel down through the layers.
First go to Photoshop’s Layers pane, and make sure all the layers are unlocked. This allows the Move Layer tool to come into play, not to move layers, but identify layers by selecting them in the Layers pane when you click the corresponding part of the image. Once you’ve identified a layer, Alt-Click it, and all other layers in the image will be hidden, allowing you to figure out exactly how the thing should look.
Mostly when I’m paring down Photoshop layers I’m looking to isolate them so that I can figure out the colour gradients they use. You could, of course, navigate your way through Photoshop’s dialogs to read off the exact RGB values. Or, if you can get the layer on its lonesome, you can use Expression Blend’s Gradient Dropper tool. ![]()
This is a brilliant little timesaver. In the Blend Property pane, select the Brush property of your choice, put it into Gradient mode, click the Gradient Dropper tool, then drag over any area on screen, and Blend will reproduce the gradient under the cursor in XAML form.
After all that, I have the first feather of the new swan: a header bar matching the Photoshop design. Well, the background of the header bar. It needs fleshing out with some buttons.
Let it Live: Control Templates and Visual States
Silverlight, following WPF, has the concept of look-less controls. That is, the Controls (take Button as an example) manage their behaviour (Buttons respond to mouse clicks by executing commands) but don’t define how they are rendered on screen. That is left to the control’s Style, and specifically its ControlTemplate. The ControlTemplate defines the visual tree of all the UI elements needed to present the control and make it look snazzy. With a little patience, some assistance from Expression Blend, and plenty of application of the Gradient Dropper tool, it’s possible to take the built-in controls and make them look and feel just how the designer ordered.
I wanted Buttons that look like those in the header bar of the Photoshop design, but when the corresponding page is selected, they should change to have a background gradient with colours like the RavenDb logo.
When restyling a Control, it’s best to start by modifying the existing style. This way you can be sure you won’t miss an aspect of the control’s behaviour that you might otherwise forget. Blend makes this easy by giving you the option of editing a copy of the Control’s current ControlTemplate (right-click on it in the Objects and Timeline View, then select Edit Template > Edit a Copy). There are occasions when that little trick has failed, and I’ve ended up with an empty control template. But MSDN has come through for me then: it has a whole section containing the default Styles and Control Templates for all the built-in controls, like this one for Button.
Part of the ControlTemplate defines how the control looks in its various states, when the mouse is over it, when it has focus, or when it is selected, for example. The Control itself is responsible for indicating when it has entered each state. As a designer, it’s your job to specify Storyboards that are activated each time particular states are entered. Each Storyboard can animate whichever properties it likes to achieve the desired effect – in my Buttons, for example, I animate the opacity property of a Border element to fade in a coloured background indicating that it is selected. All this is overseen by the VisualStateManager, of which, more here. Naturally, Expression Blend has great editing support for visual states. Read John Papa’s tutorial to learn more.
So now I have a header bar with buttons that change colour when the corresponding page is selected. Where next?
Textured Backgrounds
Well, that page background could do with spicing up. The Photoshop design has a nice textured background, which I extracted to a PNG file that Silverlight would understand by hiding every layer except the background, then using Photoshop’s “Save for Web & Devices” feature.
The thing about textured backgrounds is that you do want them to cover the whole of the page background, which means tiling the texture to fill all the space. WPF makes this easy with its ImageBrush, which has a TileMode property, which, when set to a value other than None, automatically repeats the image over the whole area to be painted by the brush. Silverlight has ImageBrushes, but they don’t support tiling out of the box. Fortunately, Phil Middlemiss has supplied what is lacking in the form of the TiledBGControl which does exactly what I need – you should take a look: it makes clever use of Silverlight’s pixel shader effects.
This is what we’ve got so far.
The Index Editor Page, Before and After
Here are a couple of other pages I’ve beautified. First, the Index Editor page, as it was before:
And now:
Again, it was a challenge knowing where to apply my beautician’s brush first. I settled on adding the header bar at the top, and I then realised it could double up as a toolbar. Originally the page had no header at all, but by having a bread-crumb bar in the header it helps to give the user a bit more context when they’re looking at the page, as well as making it easier to navigate around.
Inspiration and Icons
Since my graphic-design skills are so underdeveloped, I borrow ideas shamelessly wherever I find something that fits. You may recognise the styling of the toolbar buttons in the Index page header bar as being remarkably similar to the ones on the Google Chrome toolbar. Yes – Expression Blend’s Gradient dropper does work on live applications too! Two places to check out if you find yourself short on inspiration are Quince and Pattern Tab which both catalogue examples of user interface and user experience design from across the web. Pattern Tab especially has myriad examples of beautiful UIs.
In the past I’ve struggled to find icons for my projects, but I’ve recently discovered two great sources: IconFinder.com and IconArchive.com. Both have excellent search facilities (which is often what’s missing from the commercial collections you buy and download to your machine in a whacking great zip file), and are careful to call out the license attached to each icon. A surprisingly large number are licensed so that they can be used without charge in commercial products.
A XAML Tip
The nice thing about styling an application is that it gets easier with every page you complete. Once you’ve settled on a look for a particular kind of element, you can repeat that look on every page. Silverlight’s support for Styles and Resources makes this very easy. And I have a tip that can make it easier still.
I put all my styles into a single resource dictionary, Styles.xaml which I merge into my App.xaml resource dictionary. I then name all my Styles, Brushes, etc. using a hierarchical naming convention. So Styles all begin with “Style_”, Styles for Buttons would all begin “Style_Button”, and then would come the styles for different purposes: “Style_Button_Toolbar”, “Style_Button_Hero” (for those big red buttons in your app that the hero uses to save the world), etc.. The pay-off for using this convention comes when you’re hand-editing XAML and making use of Resharper’s XAML intellisense. Type “{StaticResource Style_[ControlType]” and Resharper instantly presents you with a list of all the styles that might apply.
A Parting Screenshot
To finish, here’s one more before and after comparison, this time of the Edit Document page. Before:
And after:
You can begin to sense the benefit of using a consistent set of styles, as it brings a harmonious feel to the whole application.
I hope you’ve enjoyed this whistle-stop tour of the Raven Studio beautification process. Remember that all the code is available on GitHub. We’d love to hear what you think.
XAML Magic: Turning an Ugly Silverlight Duckling into a Beautiful Photoshopped Swan
This is a guest post by Samuel Jack, who had done a lot of work on the new UI for RavenDB.
Three weeks ago Ayende put out a request for help in turning an ugly duckling into a beautiful swan, and I, rather nervously, signed up for the job. The ugly duckling in question was Raven Studio, the Silverlight-based management UI for Raven Db. The nerves were a result of doubting that my limited graphic design skills were up to the job. But when Ayende assured me that he had a proto-type swan in the form of a Photoshop design, drawn up by a bona-fide, turtle-neck-wearing designer, they were calmed. Marginally.
Because the design Ayende had was for the new-look RavenDb website.
He wanted me to take the look and feel and transfer it to the Silverlight Raven Studio application. Which, when he handed it over to me, looked like this:
Ahh! Where to start?
Photoshop for Developer Dummies
To ease myself in, I got started by simply trying to imitate parts of the Photoshop design in XAML, beginning with the header bar at the very top of the page. Not being a designer myself, I’m rather like a duck out of water when it comes to Photoshop, but I’ve at least got the basics sussed.
The thing to understand is that designers construct Photoshop images like onions, layer upon layer, sometimes eye-watering in complexity, and to reproduce the design, you have to peel down through the layers.
First go to Photoshop’s Layers pane, and make sure all the layers are unlocked. This allows the Move Layer tool to come into play, not to move layers, but identify layers by selecting them in the Layers pane when you click the corresponding part of the image. Once you’ve identified a layer, Alt-Click it, and all other layers in the image will be hidden, allowing you to figure out exactly how the thing should look.
Mostly when I’m paring down Photoshop layers I’m looking to isolate them so that I can figure out the colour gradients they use. You could, of course, navigate your way through Photoshop’s dialogs to read off the exact RGB values. Or, if you can get the layer on its lonesome, you can use Expression Blend’s Gradient Dropper tool. ![]()
This is a brilliant little timesaver. In the Blend Property pane, select the Brush property of your choice, put it into Gradient mode, click the Gradient Dropper tool, then drag over any area on screen, and Blend will reproduce the gradient under the cursor in XAML form.
After all that, I have the first feather of the new swan: a header bar matching the Photoshop design. Well, the background of the header bar. It needs fleshing out with some buttons.
Let it Live: Control Templates and Visual States
Silverlight, following WPF, has the concept of look-less controls. That is, the Controls (take Button as an example) manage their behaviour (Buttons respond to mouse clicks by executing commands) but don’t define how they are rendered on screen. That is left to the control’s Style, and specifically its ControlTemplate. The ControlTemplate defines the visual tree of all the UI elements needed to present the control and make it look snazzy. With a little patience, some assistance from Expression Blend, and plenty of application of the Gradient Dropper tool, it’s possible to take the built-in controls and make them look and feel just how the designer ordered.
I wanted Buttons that look like those in the header bar of the Photoshop design, but when the corresponding page is selected, they should change to have a background gradient with colours like the RavenDb logo.
When restyling a Control, it’s best to start by modifying the existing style. This way you can be sure you won’t miss an aspect of the control’s behaviour that you might otherwise forget. Blend makes this easy by giving you the option of editing a copy of the Control’s current ControlTemplate (right-click on it in the Objects and Timeline View, then select Edit Template > Edit a Copy). There are occasions when that little trick has failed, and I’ve ended up with an empty control template. But MSDN has come through for me then: it has a whole section containing the default Styles and Control Templates for all the built-in controls, like this one for Button.
Part of the ControlTemplate defines how the control looks in its various states, when the mouse is over it, when it has focus, or when it is selected, for example. The Control itself is responsible for indicating when it has entered each state. As a designer, it’s your job to specify Storyboards that are activated each time particular states are entered. Each Storyboard can animate whichever properties it likes to achieve the desired effect – in my Buttons, for example, I animate the opacity property of a Border element to fade in a coloured background indicating that it is selected. All this is overseen by the VisualStateManager, of which, more here. Naturally, Expression Blend has great editing support for visual states. Read John Papa’s tutorial to learn more.
So now I have a header bar with buttons that change colour when the corresponding page is selected. Where next?
Textured Backgrounds
Well, that page background could do with spicing up. The Photoshop design has a nice textured background, which I extracted to a PNG file that Silverlight would understand by hiding every layer except the background, then using Photoshop’s “Save for Web & Devices” feature.
The thing about textured backgrounds is that you do want them to cover the whole of the page background, which means tiling the texture to fill all the space. WPF makes this easy with its ImageBrush, which has a TileMode property, which, when set to a value other than None, automatically repeats the image over the whole area to be painted by the brush. Silverlight has ImageBrushes, but they don’t support tiling out of the box. Fortunately, Phil Middlemiss has supplied what is lacking in the form of the TiledBGControl which does exactly what I need – you should take a look: it makes clever use of Silverlight’s pixel shader effects.
This is what we’ve got so far.
The Index Editor Page, Before and After
Here are a couple of other pages I’ve beautified. First, the Index Editor page, as it was before:
And now:
Again, it was a challenge knowing where to apply my beautician’s brush first. I settled on adding the header bar at the top, and I then realised it could double up as a toolbar. Originally the page had no header at all, but by having a bread-crumb bar in the header it helps to give the user a bit more context when they’re looking at the page, as well as making it easier to navigate around.
Inspiration and Icons
Since my graphic-design skills are so underdeveloped, I borrow ideas shamelessly wherever I find something that fits. You may recognise the styling of the toolbar buttons in the Index page header bar as being remarkably similar to the ones on the Google Chrome toolbar. Yes – Expression Blend’s Gradient dropper does work on live applications too! Two places to check out if you find yourself short on inspiration are Quince and Pattern Tab which both catalogue examples of user interface and user experience design from across the web. Pattern Tab especially has myriad examples of beautiful UIs.
In the past I’ve struggled to find icons for my projects, but I’ve recently discovered two great sources: IconFinder.com and IconArchive.com. Both have excellent search facilities (which is often what’s missing from the commercial collections you buy and download to your machine in a whacking great zip file), and are careful to call out the license attached to each icon. A surprisingly large number are licensed so that they can be used without charge in commercial products.
A XAML Tip
The nice thing about styling an application is that it gets easier with every page you complete. Once you’ve settled on a look for a particular kind of element, you can repeat that look on every page. Silverlight’s support for Styles and Resources makes this very easy. And I have a tip that can make it easier still.
I put all my styles into a single resource dictionary, Styles.xaml which I merge into my App.xaml resource dictionary. I then name all my Styles, Brushes, etc. using a hierarchical naming convention. So Styles all begin with “Style_”, Styles for Buttons would all begin “Style_Button”, and then would come the styles for different purposes: “Style_Button_Toolbar”, “Style_Button_Hero” (for those big red buttons in your app that the hero uses to save the world), etc.. The pay-off for using this convention comes when you’re hand-editing XAML and making use of Resharper’s XAML intellisense. Type “{StaticResource Style_[ControlType]” and Resharper instantly presents you with a list of all the styles that might apply.
A Parting Screenshot
To finish, here’s one more before and after comparison, this time of the Edit Document page. Before:
And after:
You can begin to sense the benefit of using a consistent set of styles, as it brings a harmonious feel to the whole application.
I hope you’ve enjoyed this whistle-stop tour of the Raven Studio beautification process. Remember that all the code is available on GitHub. We’d love to hear what you think.
XAML Magic: Turning an Ugly Silverlight Duckling into a Beautiful Photoshopped Swan
This is a guest post by Samuel Jack, who had done a lot of work on the new UI for RavenDB.
Three weeks ago Ayende put out a request for help in turning an ugly duckling into a beautiful swan, and I, rather nervously, signed up for the job. The ugly duckling in question was Raven Studio, the Silverlight-based management UI for Raven Db. The nerves were a result of doubting that my limited graphic design skills were up to the job. But when Ayende assured me that he had a proto-type swan in the form of a Photoshop design, drawn up by a bona-fide, turtle-neck-wearing designer, they were calmed. Marginally.
Because the design Ayende had was for the new-look RavenDb website.
He wanted me to take the look and feel and transfer it to the Silverlight Raven Studio application. Which, when he handed it over to me, looked like this:
Ahh! Where to start?
Photoshop for Developer Dummies
To ease myself in, I got started by simply trying to imitate parts of the Photoshop design in XAML, beginning with the header bar at the very top of the page. Not being a designer myself, I’m rather like a duck out of water when it comes to Photoshop, but I’ve at least got the basics sussed.
The thing to understand is that designers construct Photoshop images like onions, layer upon layer, sometimes eye-watering in complexity, and to reproduce the design, you have to peel down through the layers.
First go to Photoshop’s Layers pane, and make sure all the layers are unlocked. This allows the Move Layer tool to come into play, not to move layers, but identify layers by selecting them in the Layers pane when you click the corresponding part of the image. Once you’ve identified a layer, Alt-Click it, and all other layers in the image will be hidden, allowing you to figure out exactly how the thing should look.
Mostly when I’m paring down Photoshop layers I’m looking to isolate them so that I can figure out the colour gradients they use. You could, of course, navigate your way through Photoshop’s dialogs to read off the exact RGB values. Or, if you can get the layer on its lonesome, you can use Expression Blend’s Gradient Dropper tool. ![]()
This is a brilliant little timesaver. In the Blend Property pane, select the Brush property of your choice, put it into Gradient mode, click the Gradient Dropper tool, then drag over any area on screen, and Blend will reproduce the gradient under the cursor in XAML form.
After all that, I have the first feather of the new swan: a header bar matching the Photoshop design. Well, the background of the header bar. It needs fleshing out with some buttons.
Let it Live: Control Templates and Visual States
Silverlight, following WPF, has the concept of look-less controls. That is, the Controls (take Button as an example) manage their behaviour (Buttons respond to mouse clicks by executing commands) but don’t define how they are rendered on screen. That is left to the control’s Style, and specifically its ControlTemplate. The ControlTemplate defines the visual tree of all the UI elements needed to present the control and make it look snazzy. With a little patience, some assistance from Expression Blend, and plenty of application of the Gradient Dropper tool, it’s possible to take the built-in controls and make them look and feel just how the designer ordered.
I wanted Buttons that look like those in the header bar of the Photoshop design, but when the corresponding page is selected, they should change to have a background gradient with colours like the RavenDb logo.
When restyling a Control, it’s best to start by modifying the existing style. This way you can be sure you won’t miss an aspect of the control’s behaviour that you might otherwise forget. Blend makes this easy by giving you the option of editing a copy of the Control’s current ControlTemplate (right-click on it in the Objects and Timeline View, then select Edit Template > Edit a Copy). There are occasions when that little trick has failed, and I’ve ended up with an empty control template. But MSDN has come through for me then: it has a whole section containing the default Styles and Control Templates for all the built-in controls, like this one for Button.
Part of the ControlTemplate defines how the control looks in its various states, when the mouse is over it, when it has focus, or when it is selected, for example. The Control itself is responsible for indicating when it has entered each state. As a designer, it’s your job to specify Storyboards that are activated each time particular states are entered. Each Storyboard can animate whichever properties it likes to achieve the desired effect – in my Buttons, for example, I animate the opacity property of a Border element to fade in a coloured background indicating that it is selected. All this is overseen by the VisualStateManager, of which, more here. Naturally, Expression Blend has great editing support for visual states. Read John Papa’s tutorial to learn more.
So now I have a header bar with buttons that change colour when the corresponding page is selected. Where next?
Textured Backgrounds
Well, that page background could do with spicing up. The Photoshop design has a nice textured background, which I extracted to a PNG file that Silverlight would understand by hiding every layer except the background, then using Photoshop’s “Save for Web & Devices” feature.
The thing about textured backgrounds is that you do want them to cover the whole of the page background, which means tiling the texture to fill all the space. WPF makes this easy with its ImageBrush, which has a TileMode property, which, when set to a value other than None, automatically repeats the image over the whole area to be painted by the brush. Silverlight has ImageBrushes, but they don’t support tiling out of the box. Fortunately, Phil Middlemiss has supplied what is lacking in the form of the TiledBGControl which does exactly what I need – you should take a look: it makes clever use of Silverlight’s pixel shader effects.
This is what we’ve got so far.
The Index Editor Page, Before and After
Here are a couple of other pages I’ve beautified. First, the Index Editor page, as it was before:
And now:
Again, it was a challenge knowing where to apply my beautician’s brush first. I settled on adding the header bar at the top, and I then realised it could double up as a toolbar. Originally the page had no header at all, but by having a bread-crumb bar in the header it helps to give the user a bit more context when they’re looking at the page, as well as making it easier to navigate around.
Inspiration and Icons
Since my graphic-design skills are so underdeveloped, I borrow ideas shamelessly wherever I find something that fits. You may recognise the styling of the toolbar buttons in the Index page header bar as being remarkably similar to the ones on the Google Chrome toolbar. Yes – Expression Blend’s Gradient dropper does work on live applications too! Two places to check out if you find yourself short on inspiration are Quince and Pattern Tab which both catalogue examples of user interface and user experience design from across the web. Pattern Tab especially has myriad examples of beautiful UIs.
In the past I’ve struggled to find icons for my projects, but I’ve recently discovered two great sources: IconFinder.com and IconArchive.com. Both have excellent search facilities (which is often what’s missing from the commercial collections you buy and download to your machine in a whacking great zip file), and are careful to call out the license attached to each icon. A surprisingly large number are licensed so that they can be used without charge in commercial products.
A XAML Tip
The nice thing about styling an application is that it gets easier with every page you complete. Once you’ve settled on a look for a particular kind of element, you can repeat that look on every page. Silverlight’s support for Styles and Resources makes this very easy. And I have a tip that can make it easier still.
I put all my styles into a single resource dictionary, Styles.xaml which I merge into my App.xaml resource dictionary. I then name all my Styles, Brushes, etc. using a hierarchical naming convention. So Styles all begin with “Style_”, Styles for Buttons would all begin “Style_Button”, and then would come the styles for different purposes: “Style_Button_Toolbar”, “Style_Button_Hero” (for those big red buttons in your app that the hero uses to save the world), etc.. The pay-off for using this convention comes when you’re hand-editing XAML and making use of Resharper’s XAML intellisense. Type “{StaticResource Style_[ControlType]” and Resharper instantly presents you with a list of all the styles that might apply.
A Parting Screenshot
To finish, here’s one more before and after comparison, this time of the Edit Document page. Before:
And after:
You can begin to sense the benefit of using a consistent set of styles, as it brings a harmonious feel to the whole application.
I hope you’ve enjoyed this whistle-stop tour of the Raven Studio beautification process. Remember that all the code is available on GitHub. We’d love to hear what you think.
XAML Magic: Turning an Ugly Silverlight Duckling into a Beautiful Photoshopped Swan
This is a guest post by Samuel Jack, who had done a lot of work on the new UI for RavenDB.
Three weeks ago Ayende put out a request for help in turning an ugly duckling into a beautiful swan, and I, rather nervously, signed up for the job. The ugly duckling in question was Raven Studio, the Silverlight-based management UI for Raven Db. The nerves were a result of doubting that my limited graphic design skills were up to the job. But when Ayende assured me that he had a proto-type swan in the form of a Photoshop design, drawn up by a bona-fide, turtle-neck-wearing designer, they were calmed. Marginally.
Because the design Ayende had was for the new-look RavenDb website.
He wanted me to take the look and feel and transfer it to the Silverlight Raven Studio application. Which, when he handed it over to me, looked like this:
Ahh! Where to start?
Photoshop for Developer Dummies
To ease myself in, I got started by simply trying to imitate parts of the Photoshop design in XAML, beginning with the header bar at the very top of the page. Not being a designer myself, I’m rather like a duck out of water when it comes to Photoshop, but I’ve at least got the basics sussed.
The thing to understand is that designers construct Photoshop images like onions, layer upon layer, sometimes eye-watering in complexity, and to reproduce the design, you have to peel down through the layers.
First go to Photoshop’s Layers pane, and make sure all the layers are unlocked. This allows the Move Layer tool to come into play, not to move layers, but identify layers by selecting them in the Layers pane when you click the corresponding part of the image. Once you’ve identified a layer, Alt-Click it, and all other layers in the image will be hidden, allowing you to figure out exactly how the thing should look.
Mostly when I’m paring down Photoshop layers I’m looking to isolate them so that I can figure out the colour gradients they use. You could, of course, navigate your way through Photoshop’s dialogs to read off the exact RGB values. Or, if you can get the layer on its lonesome, you can use Expression Blend’s Gradient Dropper tool. ![]()
This is a brilliant little timesaver. In the Blend Property pane, select the Brush property of your choice, put it into Gradient mode, click the Gradient Dropper tool, then drag over any area on screen, and Blend will reproduce the gradient under the cursor in XAML form.
After all that, I have the first feather of the new swan: a header bar matching the Photoshop design. Well, the background of the header bar. It needs fleshing out with some buttons.
Let it Live: Control Templates and Visual States
Silverlight, following WPF, has the concept of look-less controls. That is, the Controls (take Button as an example) manage their behaviour (Buttons respond to mouse clicks by executing commands) but don’t define how they are rendered on screen. That is left to the control’s Style, and specifically its ControlTemplate. The ControlTemplate defines the visual tree of all the UI elements needed to present the control and make it look snazzy. With a little patience, some assistance from Expression Blend, and plenty of application of the Gradient Dropper tool, it’s possible to take the built-in controls and make them look and feel just how the designer ordered.
I wanted Buttons that look like those in the header bar of the Photoshop design, but when the corresponding page is selected, they should change to have a background gradient with colours like the RavenDb logo.
When restyling a Control, it’s best to start by modifying the existing style. This way you can be sure you won’t miss an aspect of the control’s behaviour that you might otherwise forget. Blend makes this easy by giving you the option of editing a copy of the Control’s current ControlTemplate (right-click on it in the Objects and Timeline View, then select Edit Template > Edit a Copy). There are occasions when that little trick has failed, and I’ve ended up with an empty control template. But MSDN has come through for me then: it has a whole section containing the default Styles and Control Templates for all the built-in controls, like this one for Button.
Part of the ControlTemplate defines how the control looks in its various states, when the mouse is over it, when it has focus, or when it is selected, for example. The Control itself is responsible for indicating when it has entered each state. As a designer, it’s your job to specify Storyboards that are activated each time particular states are entered. Each Storyboard can animate whichever properties it likes to achieve the desired effect – in my Buttons, for example, I animate the opacity property of a Border element to fade in a coloured background indicating that it is selected. All this is overseen by the VisualStateManager, of which, more here. Naturally, Expression Blend has great editing support for visual states. Read John Papa’s tutorial to learn more.
So now I have a header bar with buttons that change colour when the corresponding page is selected. Where next?
Textured Backgrounds
Well, that page background could do with spicing up. The Photoshop design has a nice textured background, which I extracted to a PNG file that Silverlight would understand by hiding every layer except the background, then using Photoshop’s “Save for Web & Devices” feature.
The thing about textured backgrounds is that you do want them to cover the whole of the page background, which means tiling the texture to fill all the space. WPF makes this easy with its ImageBrush, which has a TileMode property, which, when set to a value other than None, automatically repeats the image over the whole area to be painted by the brush. Silverlight has ImageBrushes, but they don’t support tiling out of the box. Fortunately, Phil Middlemiss has supplied what is lacking in the form of the TiledBGControl which does exactly what I need – you should take a look: it makes clever use of Silverlight’s pixel shader effects.
This is what we’ve got so far.
The Index Editor Page, Before and After
Here are a couple of other pages I’ve beautified. First, the Index Editor page, as it was before:
And now:
Again, it was a challenge knowing where to apply my beautician’s brush first. I settled on adding the header bar at the top, and I then realised it could double up as a toolbar. Originally the page had no header at all, but by having a bread-crumb bar in the header it helps to give the user a bit more context when they’re looking at the page, as well as making it easier to navigate around.
Inspiration and Icons
Since my graphic-design skills are so underdeveloped, I borrow ideas shamelessly wherever I find something that fits. You may recognise the styling of the toolbar buttons in the Index page header bar as being remarkably similar to the ones on the Google Chrome toolbar. Yes – Expression Blend’s Gradient dropper does work on live applications too! Two places to check out if you find yourself short on inspiration are Quince and Pattern Tab which both catalogue examples of user interface and user experience design from across the web. Pattern Tab especially has myriad examples of beautiful UIs.
In the past I’ve struggled to find icons for my projects, but I’ve recently discovered two great sources: IconFinder.com and IconArchive.com. Both have excellent search facilities (which is often what’s missing from the commercial collections you buy and download to your machine in a whacking great zip file), and are careful to call out the license attached to each icon. A surprisingly large number are licensed so that they can be used without charge in commercial products.
A XAML Tip
The nice thing about styling an application is that it gets easier with every page you complete. Once you’ve settled on a look for a particular kind of element, you can repeat that look on every page. Silverlight’s support for Styles and Resources makes this very easy. And I have a tip that can make it easier still.
I put all my styles into a single resource dictionary, Styles.xaml which I merge into my App.xaml resource dictionary. I then name all my Styles, Brushes, etc. using a hierarchical naming convention. So Styles all begin with “Style_”, Styles for Buttons would all begin “Style_Button”, and then would come the styles for different purposes: “Style_Button_Toolbar”, “Style_Button_Hero” (for those big red buttons in your app that the hero uses to save the world), etc.. The pay-off for using this convention comes when you’re hand-editing XAML and making use of Resharper’s XAML intellisense. Type “{StaticResource Style_[ControlType]” and Resharper instantly presents you with a list of all the styles that might apply.
A Parting Screenshot
To finish, here’s one more before and after comparison, this time of the Edit Document page. Before:
And after:
You can begin to sense the benefit of using a consistent set of styles, as it brings a harmonious feel to the whole application.
I hope you’ve enjoyed this whistle-stop tour of the Raven Studio beautification process. Remember that all the code is available on GitHub. We’d love to hear what you think.
Sneak peek at the new RavenDB Studio
We started to develop the next generation of RavenDB Studio and I wanted to share a screenshot of first take of the new UI in order to gather some feedback:
The main goals of the new UI are:
- Responsiveness. You can’t see this in this picture but the UI that we play with now is very responsive.
- Easy to use. The UI should be simple and very easy to use.
- Easy to understand. This goal is to create a project that is very easy to contribute to. So far, we had very little contributions to the Studio, no doubt because the current version is quite complex. We are trying to make it very easy to understand and work with the new studio, so if you have a problem or want a new feature, it would be trivial to add and contribute.
Sneak peek at the new RavenDB Studio
We started to develop the next generation of RavenDB Studio and I wanted to share a screenshot of first take of the new UI in order to gather some feedback:
The main goals of the new UI are:
- Responsiveness. You can’t see this in this picture but the UI that we play with now is very responsive.
- Easy to use. The UI should be simple and very easy to use.
- Easy to understand. This goal is to create a project that is very easy to contribute to. So far, we had very little contributions to the Studio, no doubt because the current version is quite complex. We are trying to make it very easy to understand and work with the new studio, so if you have a problem or want a new feature, it would be trivial to add and contribute.
RavenDB Webinar #1 now available on YouTube
The first ever RavenDB webinar aired last week, Thursday the 8th, and it was a great success. We announced it only about 12 hours in advance, yet 260+ people registered. Unfortunately the software we were using only allowed 100 people in – our apologies for all of you who wanted to participate but couldn’t get in, or heard of it too late.
We have now uploaded the recording to our YouTube channel here, and you can watch it from there. Embedded here is the first part:
The other parts are available from our YouTube channel: www.youtube.com/user/HibernatingRhinos.
We had a second webinar last Friday, and had a very good Q&A session during it. Unfortunately _someone_ forgot to press the “Record” button, and there we are all left with no recording…
RavenDB webinars are here to stay. We are still formulating our plans for future webcasts – both in terms of a format and topics. The general idea is that whenever there will be enough demand, we will do a webcast on a specific topic, or just a Q&A session. Ideally we would like to have a bi-weekly session, and by the time we settle on a format you can expect many more spontaneous sessions like we had last week…
This is why we would really like to hear back from you. What are you looking for to have, when, in what format. Any other feedback – here or in the RavenDB mailing list – is definitely welcome.
See you all in our next webinars…
RavenDB Webinar #1 now available on YouTube
The first ever RavenDB webinar aired last week, Thursday the 8th, and it was a great success. We announced it only about 12 hours in advance, yet 260+ people registered. Unfortunately the software we were using only allowed 100 people in – our apologies for all of you who wanted to participate but couldn’t get in, or heard of it too late.
We have now uploaded the recording to our YouTube channel here, and you can watch it from there. Embedded here is the first part:
The other parts are available from our YouTube channel: www.youtube.com/user/HibernatingRhinos.
We had a second webinar last Friday, and had a very good Q&A session during it. Unfortunately _someone_ forgot to press the “Record” button, and there we are all left with no recording…
RavenDB webinars are here to stay. We are still formulating our plans for future webcasts – both in terms of a format and topics. The general idea is that whenever there will be enough demand, we will do a webcast on a specific topic, or just a Q&A session. Ideally we would like to have a bi-weekly session, and by the time we settle on a format you can expect many more spontaneous sessions like we had last week…
This is why we would really like to hear back from you. What are you looking for to have, when, in what format. Any other feedback – here or in the RavenDB mailing list – is definitely welcome.
See you all in our next webinars…
Entity Framework Profiler supports for LinqPAD
If you’re using LinqPAD and wants to profile your Entity Framework usage with the Entity Framework Profiler, you can use the following snippet of code in order to achieve that:
void Main()
{
HibernatingRhinos.Profiler.Appender.EntityFramework.EntityFrameworkProfiler.Initialize();
Blogs.Take(50).Dump();
}
Please make sure to use the "C# Program" option from the "language" ComboBox, and that’s it. You can now see the the profiling data in the Entity Framework Profiler.
Entity Framework Profiler supports for LinqPAD
If you’re using LinqPAD and wants to profile your Entity Framework usage with the Entity Framework Profiler, you can use the following snippet of code in order to achieve that:
void Main()
{
HibernatingRhinos.Profiler.Appender.EntityFramework.EntityFrameworkProfiler.Initialize();
Blogs.Take(50).Dump();
}
Please make sure to use the "C# Program" option from the "language" ComboBox, and that’s it. You can now see the the profiling data in the Entity Framework Profiler.
RavenDB is now on Freenode
Our mailing list is probably the most responsive one around. Nevertheless, we thought having an IRC channel could come in handy, so the community would have a place to hang around in, and perhaps also get questions answered quicker once the channel gets big enough.
Come visit us at #RavenDB on Freenode!
BTW - There are quite a few free web UIs available if you don't want to install any software, see http://webchat.freenode.net/ for example
RavenDB is now on Freenode
Our mailing list is probably the most responsive one around. Nevertheless, we thought having an IRC channel could come in handy, so the community would have a place to hang around in, and perhaps also get questions answered quicker once the channel gets big enough.
Come visit us at #RavenDB on Freenode!
BTW - There are quite a few free web UIs available if you don't want to install any software, see http://webchat.freenode.net/ for example
RavenDB gets a new face
RavenDB is already a very mature product: the official release was over a year ago, and it is already being used in production by several companies, some for about a year now. Before the official release, RavenDB has been in development for about 2.5 years, totaling more than 3.5 years of active, daily development now. Today we are mainly working on performance improvements, and on perfecting what’s already there.
So much effort has been put into development, that proper documentation was consistently lagging behind. We worked very hard on creating the most awesome document-oriented database around, that we hardly put any thought on visibility, and on spreading the word.
Now that the API has stabilized, and the product is definitely in a very good shape to say the least, it is time to redirect some efforts for making the documentation more comprehensive and up-to-date, and for letting people know how awesome RavenDB is.
The first step for doing this is giving RavenDB a face, a logo, something that people would recognize. After a few weeks of work and polls, we now have a final logo:

We are already hard at work on the next steps – redesigning the website, and creating better user experience with it. Documentation is also catching up quite nicely, and we will soon be blogging about this separately (there’s much to tell…).
You can now also follow the RavenDB project on Twitter: @RavenDB . Starting today, we will be posting updates there as well.
Stay tuned while we work on making RavenDB even more awesome!
RavenDB gets a new face
RavenDB is already a very mature product: the official release was over a year ago, and it is already being used in production by several companies, some for about a year now. Before the official release, RavenDB has been in development for about 2.5 years, totaling more than 3.5 years of active, daily development now. Today we are mainly working on performance improvements, and on perfecting what’s already there.
So much effort has been put into development, that proper documentation was consistently lagging behind. We worked very hard on creating the most awesome document-oriented database around, that we hardly put any thought on visibility, and on spreading the word.
Now that the API has stabilized, and the product is definitely in a very good shape to say the least, it is time to redirect some efforts for making the documentation more comprehensive and up-to-date, and for letting people know how awesome RavenDB is.
The first step for doing this is giving RavenDB a face, a logo, something that people would recognize. After a few weeks of work and polls, we now have a final logo:

We are already hard at work on the next steps – redesigning the website, and creating better user experience with it. Documentation is also catching up quite nicely, and we will soon be blogging about this separately (there’s much to tell…).
You can now also follow the RavenDB project on Twitter: @RavenDB . Starting today, we will be posting updates there as well.
Stay tuned while we work on making RavenDB even more awesome!
Entity Framework June 2011 CTP (v4.2) is now supported in Entity Framework Profiler
When Entity Framework June 2011 CTP was out, we were asked by our users to provide support for it in the Entity Framework Profiler.
As we started to investigate how to provide support for it, we discovered that it’s not that easy task to do. The way that Entity Framework Profiler appender works in nutshell is by replacing the instances of DbProviderFactory (like SqlClientFactory or OracleClientFactory) that the client has on his machine with a custom provider factory that wrap the original provider factory. This wasn’t easy task to do, because Entity Framework June CTP made a few assumptions that make our life more complicated. Specifically:
- There is an assumption that the provider factory type is not a generic type. This broke our code which is uses a generic provider factory type which wrap each of the providers factories that the client have on the fly, since the client can use any provider factory that he wants.
- Even if we use non-generic providers for each of the client’s providers, we found out that each provider should be compiled in a separate assembly because of the way that Entity Framework matches providers.
We’re working with the Entity Framework team in order to find a solution for this in the future versions, but in the mean time if you’re using the Entity Framework June 2011 CTP we temporary worked around this issue with a temp API that by providing a non-generic provider factory of type SqlClientFactory, which means that in the meantime you’ll be able to use the Entity Framework profiler only with Sql Server:
EntityFrameworkProfiler.TempApi_InitializeForV42_CTP();
In addition, you’ll need to add the following assembly redirection to your config file in order to instruct the profiler to use the correct version of Entity Framework:
<runtime> <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> <dependentAssembly> <assemblyIdentity name="System.Data.Entity" publicKeyToken="b77a5c561934e089" culture="neutral" /> <bindingRedirect oldVersion="4.0.0.0" newVersion="4.2.0.0" /> </dependentAssembly> </assemblyBinding> </runtime>
The main problem is that we can’t currently easily support providers other than SqlClient, if you do need that support on the new CTP, please let us know, and we will provide you with a custom version for that purpose. Considering that this is a CTP version, we decided to provide a partial solution that will work for most of our users and we’re working with the Entity Framework team in order to find a better solution.
Happy Profiling
The Hibernating Rhinos Team
Entity Framework June 2011 CTP (v4.2) is now supported in Entity Framework Profiler
When Entity Framework June 2011 CTP was out, we were asked by our users to provide support for it in the Entity Framework Profiler.
As we started to investigate how to provide support for it, we discovered that it’s not that easy task to do. The way that Entity Framework Profiler appender works in nutshell is by replacing the instances of DbProviderFactory (like SqlClientFactory or OracleClientFactory) that the client has on his machine with a custom provider factory that wrap the original provider factory. This wasn’t easy task to do, because Entity Framework June CTP made a few assumptions that make our life more complicated. Specifically:
- There is an assumption that the provider factory type is not a generic type. This broke our code which is uses a generic provider factory type which wrap each of the providers factories that the client have on the fly, since the client can use any provider factory that he wants.
- Even if we use non-generic providers for each of the client’s providers, we found out that each provider should be compiled in a separate assembly because of the way that Entity Framework matches providers.
We’re working with the Entity Framework team in order to find a solution for this in the future versions, but in the mean time if you’re using the Entity Framework June 2011 CTP we temporary worked around this issue with a temp API that by providing a non-generic provider factory of type SqlClientFactory, which means that in the meantime you’ll be able to use the Entity Framework profiler only with Sql Server:
EntityFrameworkProfiler.TempApi_InitializeForV42_CTP();
In addition, you’ll need to add the following assembly redirection to your config file in order to instruct the profiler to use the correct version of Entity Framework:
<runtime> <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> <dependentAssembly> <assemblyIdentity name="System.Data.Entity" publicKeyToken="b77a5c561934e089" culture="neutral" /> <bindingRedirect oldVersion="4.0.0.0" newVersion="4.2.0.0" /> </dependentAssembly> </assemblyBinding> </runtime>
The main problem is that we can’t currently easily support providers other than SqlClient, if you do need that support on the new CTP, please let us know, and we will provide you with a custom version for that purpose. Considering that this is a CTP version, we decided to provide a partial solution that will work for most of our users and we’re working with the Entity Framework team in order to find a better solution.
Happy Profiling
The Hibernating Rhinos Team
Entity Framework June 2011 CTP (v4.2) is now supported in Entity Framework Profiler
When Entity Framework June 2011 CTP was out, we were asked by our users to provide support for it in the Entity Framework Profiler.
As we started to investigate how to provide support for it, we discovered that it’s not that easy task to do. The way that Entity Framework Profiler appender works in nutshell is by replacing the instances of DbProviderFactory (like SqlClientFactory or OracleClientFactory) that the client has on his machine with a custom provider factory that wrap the original provider factory. This wasn’t easy task to do, because Entity Framework June CTP made a few assumptions that make our life more complicated. Specifically:
- There is an assumption that the provider factory type is not a generic type. This broke our code which is uses a generic provider factory type which wrap each of the providers factories that the client have on the fly, since the client can use any provider factory that he wants.
- Even if we use non-generic providers for each of the client’s providers, we found out that each provider should be compiled in a separate assembly because of the way that Entity Framework matches providers.
We’re working with the Entity Framework team in order to find a solution for this in the future versions, but in the mean time if you’re using the Entity Framework June 2011 CTP we temporary worked around this issue with a temp API that by providing a non-generic provider factory of type SqlClientFactory, which means that in the meantime you’ll be able to use the Entity Framework profiler only with Sql Server:
EntityFrameworkProfiler.TempApi_InitializeForV42_CTP();
In addition, you’ll need to add the following assembly redirection to your config file in order to instruct the profiler to use the correct version of Entity Framework:
<runtime> <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> <dependentAssembly> <assemblyIdentity name="System.Data.Entity" publicKeyToken="b77a5c561934e089" culture="neutral" /> <bindingRedirect oldVersion="4.0.0.0" newVersion="4.2.0.0" /> </dependentAssembly> </assemblyBinding> </runtime>
The main problem is that we can’t currently easily support providers other than SqlClient, if you do need that support on the new CTP, please let us know, and we will provide you with a custom version for that purpose. Considering that this is a CTP version, we decided to provide a partial solution that will work for most of our users and we’re working with the Entity Framework team in order to find a better solution.
Happy Profiling
The Hibernating Rhinos Team
RavenDB Profiling Support
When we built the RavenDB profiling support, we intentionally built it in such a way that you can have multiple ways of accessing it.
Out of the box, we come with a VS debugger visualizer and an MVC Profiler for your websites. The VS Debugger Visualizer is pretty ugly (fully functional, of course, just not that pretty), but we are very proud of the MVC Profiler support and how it looks:
The real fun part is that we aren’t the only ones that can access those API, the screen shot below was taken from a Glimpse extension that adds RavenDB Profiling support:
That is quite impressive, even if I say so myself, and it shows what happen when you aren’t overly fond of the internal keyword.
RavenDB Profiling Support
When we built the RavenDB profiling support, we intentionally built it in such a way that you can have multiple ways of accessing it.
Out of the box, we come with a VS debugger visualizer and an MVC Profiler for your websites. The VS Debugger Visualizer is pretty ugly (fully functional, of course, just not that pretty), but we are very proud of the MVC Profiler support and how it looks:
The real fun part is that we aren’t the only ones that can access those API, the screen shot below was taken from a Glimpse extension that adds RavenDB Profiling support:
That is quite impressive, even if I say so myself, and it shows what happen when you aren’t overly fond of the internal keyword.
RavenDB in Practice, Part 2 - Using the Client API
This series is about how to start using RavenDB without any prior knowledge about Document Databases. There is assumption that you’re familiar with Relational Databases like Sql Server, though.
In the introduction post of this series I briefly examined what is a Document Database, what is a document and how RavenDB Management Studio looks like. Now it’s time to show you how to actually use RavenDB in your applications. So let’s talk about the client API.
The target of this post is to show you how to use the client API: we’ll start by creating a basic model entity, than we’re going to store an instance of this entity in RavenDB database, then load a entity and update it. Finally, I’m going to show you how to do some more complex queries.
You can use RavenDB from any language or platform (more on that in a future blog post). In this blog post we’re going to use the .NET client API which let you consume RavenDB from any .NET application very easily.
Let’s create an empty ASP.NET MVC application and add the following the RavenDB NuGet package to it:
After the RavenDB NuGet package has been installed you’re ready to start use RavenDB from the MVC application that we created. But we need first need to make sure that we have a RavenDB database to connect to. In order to that, run the RavenDB console application as we did in the previous post, and edit the connection string in the web.config to point to the correct server URL:
<connectionStrings> <add name="RavenDB" connectionString="Url=http://localhost:8080" /> </connectionStrings>
Now that we have RavenDB and the Client API set up, it’s time to do something interesting with it. In order to start interacting with RavenDB with the Client API you’ll need to create an instance of the IDocumentSession and the IDocumentStore. The session is define the boundaries of your Unit Of Work, which will be in a typical web application the entire web request, and the IDocumentStore lets you create sessions. It’s a good practice to create one instance of IDocumentStore per application and one session per unit of work.
Showing how to effectively managing the session in a web application is out of the scope of this blog post (which require us talking us to talk about IoC patterns), but you can take a look on the RaccoonBlog project in order to see one simple approach to achieve this. The RaccoonBlog project was created specifically for demonstration purposes in this blog posts series and it’s now the blog engine that we use to run this blog).
For this demonstration we’re going to create the session and the document store directly in the controller. As specified in the above paragraph, in real applications you’ll typically want to manage the session out of the controller.
public class ProductController : Controller { private static readonly IDocumentStore documentStore; private IDocumentSession _session; static ProductController() { documentStore = new DocumentStore { ConnectionStringName = "RavenDB" }.Initialize(); } protected override void OnActionExecuting(ActionExecutingContext filterContext) { _session = documentStore.OpenSession(); } protected override void OnActionExecuted(ActionExecutedContext filterContext) { _session.SaveChanges(); _session.Dispose(); } }
Now that we have the session in place, we can start using it to do CRUD operations on the database. Consider the following Product entity which we’re going to use in this blog post:
public class Product { public string Id { get; set; } public string CategoryId { get; set; } public string SupplierId { get; set; } public string Name { get; set; } public string Code { get; set; } public decimal StandardCost { get; set; } public decimal ListPrice { get; set; } public int UnitsOnStock { get; set; } public int UnitsOnOrder { get; set; } public bool Discontinued { get; set; } public string PhotoFile { get; set; } public DateTime CreatedAt { get; set; } }
Let’s create an instance of this entity and store it into the database:
public ActionResult StoreSomeProductInDatabase() { var product = new Product { Name = "Product Name", CategoryId = "category/1024", SupplierId = "supplier/16", Code = "H11050", CreatedAt = DateTime.Now, StandardCost = 250, ListPrice = 189, FilePhoto = "path to picture.jpg", }; _session.Store(product); _session.SaveChanges(); return Content(product.Id); }
First we’re creating a product and storing it in the session. I said we’re storing it in the session because when you call the _session.Store(product) method it wouldn’t send the product to the database yet. In order to actually save the product in the database you’ll need to call the _session.SaveChanges(). Note that after you call the _session.SaveChanges() method we can use the product.Id, which will be “products/1”. We didn’t assign that Id manually but let the client API assigns it to us automatically. If you’ll look on the RavenDB console application you’ll see the following log output:
Raven is ready to process requests. Build 385, Version 1.0.0.0 / 64f1188
Server started in 2,519 ms
Data directory: C:\Users\Fitzchak\Downloads\RavenDB-Unstable-Build-385\Server\Data
HostName: <any> Port: 8080, Storage: Esent
Server Url: http://fitzchak-pc:8080/
Press <enter> to stop or 'cls' and <enter> to clear the log
Request # 1: GET - 26 ms - <default> - 404 - /docs/Raven/Replication/Destinations
Request # 2: GET - 0 ms - <default> - 404 - /docs/Raven/Hilo/products
Request # 3: PUT - 241 ms - <default> - 201 - /docs/Raven/Hilo/products
Request # 4: POST - 44 ms - <default> - 200 - /bulk_docs
PUT products/1
At request #4 we can see the actual post request which will store the products/1 document. We got response status #200 which means that the document is successfully stored in the database. In addition you can see that we do not need to query the database and ask what was the generated id for our product (which is a typically case with auto increase field implementation in relational databases), because the Id is generated by the client API (which use the HiLo algorithm to generate it). This “magic” happens in request #2 and #3 which we’ll be covered in the upcoming posts.
You can look on the RavenDB Management Studio in order to see the documents that we just stored:
We could have also store a lot of products in the session and than call the SaveChanges which will insert all of them to the database with just one call:
public ActionResult InsertSomeMoreProducts() { for (int i = 0; i < 50; i++) { var product = new Product { Name = "Product Name " + i, CategoryId = "category/1024", SupplierId = "supplier/16", Code = "H11050" + i, CreatedAt = DateTime.Now, StandardCost = 250 + (i * 10), ListPrice = 189 + (i * 10), }; _session.Store(product); } _session.SaveChanges(); return Content("Products successfully created"); }
This will create 50 documents in the database with just one call to the database, as you can see in the RavenDB console output (I substitute some of the log output with … for space reasons):
Request # 5: POST - 17 ms - <default> - 200 - /bulk_docs
PUT products/2
PUT products/3
PUT products/4
PUT products/5
...
PUT products/49
PUT products/50
PUT products/51
This how it’s looks like on the Management Studio:
Now that we have a few documents in the database it’s time to see how we can load one of them. In order to load the entire document you can use the Load method:
Product product = _session.Load<Product>("products/5"); Product product2 = _session.Load<Product>("5");
The above lines are equivalent, they return the same product. The second line is a handy shortcut that RavenDB Client API provides us, which can come in handy when you expose the int part of the ID as a web parameter like in the following code:
public ActionResult GetProduct(int id) { Product product = _session.Load<Product>(id); return Content(product.Name); }
In the above code we used a number in order to get the document instead of having you use the actual full ID (“products/” + id). Now it’s time to modify the product and save it to the database:
public ActionResult LoadAndUpdateProduct() { Product product = _session.Load<Product>("products/5"); product.ListPrice -= 10; _session.SaveChanges(); return Content("Product 5 successfully updated"); }
As you can see, updating a document is as simple as loading the document, changing its properties and calling the _session.SaveChanges method. This can be happening because that the session keeps track of each of the loaded entities. This lets the session determine which of the documents has been updated and send just them to the database.
What is left is to delete a document. Consider the following code which will do exactly that:
public ActionResult DeleteProduct(int id) { Product product = _session.Load<Product>(id); if (product == null) return HttpNotFound("Product {0} does not exist"); _session.Delete(product); _session.SaveChanges(); return Content(string.Format("Product {0} successfully deleted", id)); }
One interesting thing that we do here is to check if product is null. This is very important step after loading a document because that _session.Load method will return null if there is no document with the corresponding specified id in the database.
Until now we did plain CRUD operations. Now it’s time to create some more complex queries... Raven Client API comes with a great support for Linq so we can use this in order to create more complex queries. Here in an example of how we can get all the products that are available for sale (discontinued equal to false) ordered by the product’s list price:
public ActionResult GetDiscontinuedProducts() { var products = from product in _session.Query<Product>() where product.Discontinued == false orderby product.ListPrice select product; return View(products.ToList()); }
As you can see, RavenDB Client API gives you what you’ll expect from a modern database client API to support. It has great LINQ provider that you’ll let you do almost anything you can do with a regular LINQ queries.
In this post I demonstrated how easy is to use the RavenDB .NET Client API in order to store some documents in the database, load them, update and remove them. Than we saw that we can use LINQ powered queries in order to actually query the database with some criteria and order by statement.
In the future blog posts I’m going to talk about the following topics:
- Introduce the RaccoonBlog project and blog about the interesting parts of it.
- Talk about modeling entities in a way that suits documents database.
If you have any feedback / questions / suggestions regards this blog posts I’ll be more than happy to hear it.
RavenDB in Practice, Part 2 - Using the Client API
This series is about how to start using RavenDB without any prior knowledge about Document Databases. There is assumption that you’re familiar with Relational Databases like Sql Server, though.
In the introduction post of this series I briefly examined what is a Document Database, what is a document and how RavenDB Management Studio looks like. Now it’s time to show you how to actually use RavenDB in your applications. So let’s talk about the client API.
The target of this post is to show you how to use the client API: we’ll start by creating a basic model entity, than we’re going to store an instance of this entity in RavenDB database, then load a entity and update it. Finally, I’m going to show you how to do some more complex queries.
You can use RavenDB from any language or platform (more on that in a future blog post). In this blog post we’re going to use the .NET client API which let you consume RavenDB from any .NET application very easily.
Let’s create an empty ASP.NET MVC application and add the following the RavenDB NuGet package to it:
After the RavenDB NuGet package has been installed you’re ready to start use RavenDB from the MVC application that we created. But we need first need to make sure that we have a RavenDB database to connect to. In order to that, run the RavenDB console application as we did in the previous post, and edit the connection string in the web.config to point to the correct server URL:
<connectionStrings> <add name="RavenDB" connectionString="Url=http://localhost:8080" /> </connectionStrings>
Now that we have RavenDB and the Client API set up, it’s time to do something interesting with it. In order to start interacting with RavenDB with the Client API you’ll need to create an instance of the IDocumentSession and the IDocumentStore. The session is define the boundaries of your Unit Of Work, which will be in a typical web application the entire web request, and the IDocumentStore lets you create sessions. It’s a good practice to create one instance of IDocumentStore per application and one session per unit of work.
Showing how to effectively managing the session in a web application is out of the scope of this blog post (which require us talking us to talk about IoC patterns), but you can take a look on the RaccoonBlog project in order to see one simple approach to achieve this. The RaccoonBlog project was created specifically for demonstration purposes in this blog posts series and it’s now the blog engine that we use to run this blog).
For this demonstration we’re going to create the session and the document store directly in the controller. As specified in the above paragraph, in real applications you’ll typically want to manage the session out of the controller.
public class ProductController : Controller { private static readonly IDocumentStore documentStore; private IDocumentSession _session; static ProductController() { documentStore = new DocumentStore { ConnectionStringName = "RavenDB" }.Initialize(); } protected override void OnActionExecuting(ActionExecutingContext filterContext) { _session = documentStore.OpenSession(); } protected override void OnActionExecuted(ActionExecutedContext filterContext) { _session.SaveChanges(); _session.Dispose(); } }
Now that we have the session in place, we can start using it to do CRUD operations on the database. Consider the following Product entity which we’re going to use in this blog post:
public class Product { public string Id { get; set; } public string CategoryId { get; set; } public string SupplierId { get; set; } public string Name { get; set; } public string Code { get; set; } public decimal StandardCost { get; set; } public decimal ListPrice { get; set; } public int UnitsOnStock { get; set; } public int UnitsOnOrder { get; set; } public bool Discontinued { get; set; } public string PhotoFile { get; set; } public DateTime CreatedAt { get; set; } }
Let’s create an instance of this entity and store it into the database:
public ActionResult StoreSomeProductInDatabase() { var product = new Product { Name = "Product Name", CategoryId = "category/1024", SupplierId = "supplier/16", Code = "H11050", CreatedAt = DateTime.Now, StandardCost = 250, ListPrice = 189, FilePhoto = "path to picture.jpg", }; _session.Store(product); _session.SaveChanges(); return Content(product.Id); }
First we’re creating a product and storing it in the session. I said we’re storing it in the session because when you call the _session.Store(product) method it wouldn’t send the product to the database yet. In order to actually save the product in the database you’ll need to call the _session.SaveChanges(). Note that after you call the _session.SaveChanges() method we can use the product.Id, which will be “products/1”. We didn’t assign that Id manually but let the client API assigns it to us automatically. If you’ll look on the RavenDB console application you’ll see the following log output:
Raven is ready to process requests. Build 385, Version 1.0.0.0 / 64f1188
Server started in 2,519 ms
Data directory: C:\Users\Fitzchak\Downloads\RavenDB-Unstable-Build-385\Server\Data
HostName: <any> Port: 8080, Storage: Esent
Server Url: http://fitzchak-pc:8080/
Press <enter> to stop or 'cls' and <enter> to clear the log
Request # 1: GET - 26 ms - <default> - 404 - /docs/Raven/Replication/Destinations
Request # 2: GET - 0 ms - <default> - 404 - /docs/Raven/Hilo/products
Request # 3: PUT - 241 ms - <default> - 201 - /docs/Raven/Hilo/products
Request # 4: POST - 44 ms - <default> - 200 - /bulk_docs
PUT products/1
At request #4 we can see the actual post request which will store the products/1 document. We got response status #200 which means that the document is successfully stored in the database. In addition you can see that we do not need to query the database and ask what was the generated id for our product (which is a typically case with auto increase field implementation in relational databases), because the Id is generated by the client API (which use the HiLo algorithm to generate it). This “magic” happens in request #2 and #3 which we’ll be covered in the upcoming posts.
You can look on the RavenDB Management Studio in order to see the documents that we just stored:
We could have also store a lot of products in the session and than call the SaveChanges which will insert all of them to the database with just one call:
public ActionResult InsertSomeMoreProducts() { for (int i = 0; i < 50; i++) { var product = new Product { Name = "Product Name " + i, CategoryId = "category/1024", SupplierId = "supplier/16", Code = "H11050" + i, CreatedAt = DateTime.Now, StandardCost = 250 + (i * 10), ListPrice = 189 + (i * 10), }; _session.Store(product); } _session.SaveChanges(); return Content("Products successfully created"); }
This will create 50 documents in the database with just one call to the database, as you can see in the RavenDB console output (I substitute some of the log output with … for space reasons):
Request # 5: POST - 17 ms - <default> - 200 - /bulk_docs
PUT products/2
PUT products/3
PUT products/4
PUT products/5
...
PUT products/49
PUT products/50
PUT products/51
This how it’s looks like on the Management Studio:
Now that we have a few documents in the database it’s time to see how we can load one of them. In order to load the entire document you can use the Load method:
Product product = _session.Load<Product>("products/5"); Product product2 = _session.Load<Product>("5");
The above lines are equivalent, they return the same product. The second line is a handy shortcut that RavenDB Client API provides us, which can come in handy when you expose the int part of the ID as a web parameter like in the following code:
public ActionResult GetProduct(int id) { Product product = _session.Load<Product>(id); return Content(product.Name); }
In the above code we used a number in order to get the document instead of having you use the actual full ID (“products/” + id). Now it’s time to modify the product and save it to the database:
public ActionResult LoadAndUpdateProduct() { Product product = _session.Load<Product>("products/5"); product.ListPrice -= 10; _session.SaveChanges(); return Content("Product 5 successfully updated"); }
As you can see, updating a document is as simple as loading the document, changing its properties and calling the _session.SaveChanges method. This can be happening because that the session keeps track of each of the loaded entities. This lets the session determine which of the documents has been updated and send just them to the database.
What is left is to delete a document. Consider the following code which will do exactly that:
public ActionResult DeleteProduct(int id) { Product product = _session.Load<Product>(id); if (product == null) return HttpNotFound("Product {0} does not exist"); _session.Delete(product); _session.SaveChanges(); return Content(string.Format("Product {0} successfully deleted", id)); }
One interesting thing that we do here is to check if product is null. This is very important step after loading a document because that _session.Load method will return null if there is no document with the corresponding specified id in the database.
Until now we did plain CRUD operations. Now it’s time to create some more complex queries... Raven Client API comes with a great support for Linq so we can use this in order to create more complex queries. Here in an example of how we can get all the products that are available for sale (discontinued equal to false) ordered by the product’s list price:
public ActionResult GetDiscontinuedProducts() { var products = from product in _session.Query<Product>() where product.Discontinued == false orderby product.ListPrice select product; return View(products.ToList()); }
As you can see, RavenDB Client API gives you what you’ll expect from a modern database client API to support. It has great LINQ provider that you’ll let you do almost anything you can do with a regular LINQ queries.
In this post I demonstrated how easy is to use the RavenDB .NET Client API in order to store some documents in the database, load them, update and remove them. Than we saw that we can use LINQ powered queries in order to actually query the database with some criteria and order by statement.
In the future blog posts I’m going to talk about the following topics:
- Introduce the RaccoonBlog project and blog about the interesting parts of it.
- Talk about modeling entities in a way that suits documents database.
If you have any feedback / questions / suggestions regards this blog posts I’ll be more than happy to hear it.
NuGet packages and VB.net application start code
In order to support one click install experience for our profilers we’re providing our users with NuGet packages for some of our profilers. The profilers that currently have NuGet package are:
When you install one of the profiler packages, your project is updated with some application start code that wiring your application with the profiler. This is great but it’s even greater since we are fully support VB projects alongside the C# once.
One thing that it’s interesting through is that no matter what project type you’re using, C# or VB, both files types are added to your project, one for each project type:
You may think that you’re going to get compilation error here, as C# projects can’t read the .vb file and vice versa, VB projects can’t read the .cs file, but it’s actually do compile. This is because that only one of the files are going to compile with your code while the other one added as content – which means that even that the file is there you actually do not do anything interesting with it - it’s not going to compile with your code.
In a C# project the files properties will like the following:
The .cs file build action value is compile.
The .vs file build action set value is content.
It’s may not be very intuitive to see a .vb file in C# project, but this behavior is inherited by NuGet, which is responsible to add those files. Looking on the NuGet documentation I wasn’t able to see any reference regards how is it behaves on different project types.
We can remove one of the files manually from the Install.ps1 files, depends on what project type you use, but since we think that this responsibility is of NuGet, we let NuGet to take care of that.
NuGet packages and VB.net application start code
In order to support one click install experience for our profilers we’re providing our users with NuGet packages for some of our profilers. The profilers that currently have NuGet package are:
When you install one of the profiler packages, your project is updated with some application start code that wiring your application with the profiler. This is great but it’s even greater since we are fully support VB projects alongside the C# once.
One thing that it’s interesting through is that no matter what project type you’re using, C# or VB, both files types are added to your project, one for each project type:
You may think that you’re going to get compilation error here, as C# projects can’t read the .vb file and vice versa, VB projects can’t read the .cs file, but it’s actually do compile. This is because that only one of the files are going to compile with your code while the other one added as content – which means that even that the file is there you actually do not do anything interesting with it - it’s not going to compile with your code.
In a C# project the files properties will like the following:
The .cs file build action value is compile.
The .vs file build action set value is content.
It’s may not be very intuitive to see a .vb file in C# project, but this behavior is inherited by NuGet, which is responsible to add those files. Looking on the NuGet documentation I wasn’t able to see any reference regards how is it behaves on different project types.
We can remove one of the files manually from the Install.ps1 files, depends on what project type you use, but since we think that this responsibility is of NuGet, we let NuGet to take care of that.