A Custom Editable control with Silverlight

by jeppe 19. November 2010 00:40

When Armstrong landed on the moon more than 40 years ago, it was one small step for man but one big step for mankind.

Well it seems that I have achieved the opposite.  One small step for a relatively experienced silverlight/wpf developer, but one giant step for Jeppe Vammen Kristensen.

I’ve created my first custom  content control.  “Pfff” you might add. But hey it has 3 dependency properties( A concept that it has taken me a long time to fully comprehend)

Tell me more

So what is this marvelous thing that I have created? It’s a fairly simple control where you can define content for when it is being edited or not edited.

You can go to this page for an example of it in action  http://examples.jeppek.dk/TrueFalseExample/TrueFalseExampleTestPage.html. Checking the checkbox will enable and disable the IsEditing property.

Or you can download the sample code here: Source (it requires that you have Silverlight Tools installed)

The View

And here is the xaml for the example.

<UserControl x:Class="TrueFalseExample.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:Control="clr-namespace:TrueFalseExample.Control" mc:Ignorable="d"
    d:DesignHeight="300" d:DesignWidth="400">

    <Grid x:Name="LayoutRoot" Background="White">
        <StackPanel>
            <CheckBox Name="RandomCheckBox" Content="Enable Disable Editing" ></CheckBox>
            <TextBlock FontSize="16" >Simple</TextBlock>
            <Control:EditableContentControl  
                IsEditing="{Binding Path=IsChecked, ElementName=RandomCheckBox}"               
                TrueContent="Editing enabled"
                FalseContent="Editing disabled" />

            <TextBlock FontSize="16">Edit/Non Edit</TextBlock>
            <Control:EditableContentControl  
                IsEditing="{Binding Path=IsChecked, ElementName=RandomCheckBox}">
                <!-- The content for true -->                
                <Control:EditableContentControl.TrueContent>
                    <TextBox Text="{Binding Path=FullName,Mode=TwoWay}" />                    
                </Control:EditableContentControl.TrueContent>             
                
                <!-- The content for false-->
                <Control:EditableContentControl.FalseContent>
                    <TextBlock Text="{Binding Path=FullName}" />
                </Control:EditableContentControl.FalseContent>
            </Control:EditableContentControl>
            
        </StackPanel>
    </Grid>
</UserControl>

You can see that there are two examples of using the control. In the first one I simple add a text value to the TrueContent and FalseContent properties.  On both controls I have bound the IsEditing property to the IsChecked value of the checkbox.

In the last control example I’m binding to a property directly  in the view codebehind (just to keep the sample code as simple as possible).

 public partial class MainPage : INotifyPropertyChanged
    {
        public MainPage()
        {
            InitializeComponent();
            DataContext = this;
            FullName = "Jeppe Vammen Kristensen";
        }

        private string _fullName;

        public string FullName
        {
            get { return _fullName; }
            set { _fullName = value; OnPropertyChanged("FullName"); }
        }

        public void OnPropertyChanged(string propertyName)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }

        public event PropertyChangedEventHandler PropertyChanged = delegate {};
    }

A short remark on dependency properties

The code for the control is as I mentioned earlier fairly simple in it’s nature. But I use Dependency Properties, and while they are smart, they also make the code a bit complicated to understand.

It’s also difficult to explain In few words what they do. So here are some characteristics:

  • Dependency Properties are there so you can do among many things: DataBinding, Validation, Coercion , Change Notification. They are a key element when you do bind to properties. F.ex through “{Binding Path=SomeProperty}”
  • It’s like having a static backing field for your properties, where the values are stored deep inside the belly of wpf. So in short it’s value is not stored on the control instance.
  • Typically the control will wrap a property around the dependency property. For instance when you set the Text property in xaml :
    <TextBox Text="SomeValue" /> 
  • You are basically calling this on instance:
    public string Text
    {
       get { return GetValue(TextProperty);}
       set { SetValue(TextProperty, value);}
    }
  • In the previous example there is a call to GetValue and SetValue. Both take as input a Dependency Property. And the reason these methods are available is because the control is derived  from a DependencyObject(which is the only place where you can set Dependency Properties)

I’ll stop here. Don’t be alarmed if you don’t get it 100 % (or at all). It has taken me a lot of time to grasp dependency properties, and to be honest I do not now if I have fully understood it.

The Code

But to get back to the control. If we strip away the insanity (the dependency properties) this is the control we have:

image

3 properties and a control derived from a ContentControl. Let’s try to strip down the code into chunks.  In the start of the code we declare the dependency properties. It looks like this

Registering the Dependency Properties

 public static DependencyProperty TrueContentProperty =
            DependencyProperty.Register
                (
                    name: "TrueContent",
                    propertyType: typeof (object),
                    ownerType: typeof (EditableContentControl),
                    typeMetadata: new PropertyMetadata(TrueDataTemplateChanged)
                );

        public static DependencyProperty FalseContentProperty =
            DependencyProperty.Register
                (
                    name: "FalseContent",
                    propertyType: typeof (object),
                    ownerType: typeof (EditableContentControl),
                    typeMetadata: new PropertyMetadata(FalseContentChanged)
                );

        public static DependencyProperty IsEditingProperty =
            DependencyProperty.Register
                (
                    name: "IsEditing",
                    propertyType: typeof (bool),
                    ownerType: typeof (EditableContentControl),
                    typeMetadata: new PropertyMetadata(IsEditingChanged)
                );

We are registering the properties in the wpf motor. Defining the value of the property and other metadata. Be aware of the typeMetaData, here we are pointing towards a callback for when changes occur to the properties (We will get to that).

Wrapping the dependency properties in good old properties

/// <summary>
        /// The content to display when IsEditing is true
        /// </summary>
        public object TrueContent
        {
            get { return GetValue(TrueContentProperty); }
            set { SetValue(TrueContentProperty, value); }
        }

        /// <summary>
        /// The content to display when IsEditing is false
        /// </summary>
        public object FalseContent
        {
            get { return GetValue(FalseContentProperty); }
            set { SetValue(FalseContentProperty, value); }
        }
        
        public bool IsEditing
        {
            get { return (bool) GetValue(IsEditingProperty); }
            set { SetValue(IsEditingProperty, value); }
        }

These are the properties we use when we set values in xaml, and because this is done on all controls is also the reason why you generally don’t have to be concerned about Dependency Properties

Handling changes to the properties (the heart of the control)

 /// <summary>
        /// Changes the displayed content if isEditing is false and the passed
        /// in FalseContent is different from the existing
        /// </summary>
        /// <param name="d"></param>
        /// <param name="e"></param>
        private static void FalseContentChanged(DependencyObject d, 
            DependencyPropertyChangedEventArgs e)
        {
            var isEditing = ExtractBool(d.GetValue(IsEditingProperty));

            if (!isEditing && e.NewValue != e.OldValue)
                d.SetValue(ContentProperty, e.NewValue);
        }

        /// <summary>
        /// Changes the displayed content if isEditing is true and the passed
        /// in FalseContent is different from the existing
        /// </summary>
        /// <param name="d"></param>
        /// <param name="e"></param>
        private static void TrueDataTemplateChanged(DependencyObject d, 
            DependencyPropertyChangedEventArgs e)
        {
            var isEditing = ExtractBool(d.GetValue(IsEditingProperty));

            if (isEditing && e.NewValue != e.OldValue)
                d.SetValue(ContentProperty, e.NewValue);
        }

        /// <summary>
        /// Handles changes to the IsEditing property
        /// </summary>
        /// <param name="d"></param>
        /// <param name="e"></param>
        private static void IsEditingChanged(DependencyObject d, 
            DependencyPropertyChangedEventArgs e)
        {
            if (e.NewValue == e.OldValue) return;

            bool newBool = ExtractBool(e.NewValue);

            UpdateContent(newBool,d);
        }
 

I’m inspecting all property changes and based on different factors updates the Content of the control (the content is the part that will be displayed ).

  • FalseContent. If the changed value for the FalseContent is different from the old (e.NewValue vs. e.OldValue) and the IsEditing property is false. We change overwrite the current Content being displayed
  • TrueContent. The same as for FalseContent. Only we overwrite if IsEditing is true
  • IsEditing.  We determine if IsEditing has changed to a new value. And the call to the method UpdateContent will overwrite Content with the value of TrueContent or FalseContent based on what the new IsEditing value is.

The two static help methods

        private static void UpdateContent(bool isEditing, DependencyObject d)
        {
            if (isEditing)
                d.SetValue(ContentProperty, d.GetValue(TrueContentProperty));
            else
                d.SetValue(ContentProperty, d.GetValue(FalseContentProperty));
        }

        private static bool ExtractBool(object value)
        {
            if (value is bool?)
                return ((bool?)value).GetValueOrDefault(false);

            if (value is bool)
                return (bool)value;

            return false;
        }

I hope the ExtractBool is pretty self explanatory. A short comment should be attached to the UpdateContent method. We pass in the DependencyObject and since we are in a static context we can’t use the property wrapper so we use SetValue and GetValue instead.

Wrapping up

The purpose of this blog post was to try to explain how to create a  relatively simple custom control in  a silverlight/wpf  application. A certain property type that has been mentioned a lot in this post, is the key to doing that.

Button does not support text content (Windows Phone 7)

by jeppe 8. October 2010 22:41

I ran into  a minor issue when messing around with Windows Phone 7. It was easily fixed, but in my opinion a little unintuitive and frightened. I have the same relationship with it, that Lrrr has with the concept of wuv http://www.youtube.com/watch?v=khc4UaLdMKk. It confuses and infuriates me.

Here goes. I wrote this in the markup

<Button Name=”GoBack>GoBack</Button>

It compiled, but when the usercontrol in which this was placed became active I got an exception stating that Button does not support text content.

I’m not going to fly through the roof, cause it can easily be fixed, doing this

<Button Name=”GoBackContent="GoBack" ></Button>

But this can at least be done in wpf, and I am a little unimpressed that it compiles, without even given a warning.

That being said, I think it’s a nice development platform.

Issues with databinding Listbox for Windows Phone 7

by Jeppe 6. October 2010 20:41

I downloaded the developer tools for windows phone 7 yesterday. And started playing around with it, and fairly quickly came up with what will most likely be the killer app for the new Windows Phone 7 smart phones.

Things went reasonably well with creating a button in blend, and playing a sound file.  So high on the adrenaline rush the next step for me was to add different sounds to choose from and them bind them to a Listbox. And that is where I ran into some troubles. Here's a quick layout of the code:

Extract from the MainPageViewModel

private SoundEffectViewModel _currentSound;
       public SoundEffectViewModel CurrentSound
       {
           get { return _currentSound; }
           set 
           { 
               _currentSound = value; 
               NotifyOfPropertyChange(() => CurrentSound);
               NotifyOfPropertyChange(() => CanPlaySound);
           }
       }

       public ObservableCollection<SoundEffectViewModel> Sounds { get; set; }

So I have an ObservableCollection of SoundEffectViewModel  and a currently selected Item. When binding to this in xaml this was what I expected to work:

 

<ListBox x:Name="Sounds" IsSynchronizedWithCurrentItem="true"  
                 SelectedItem="{Binding Path=CurrentSound, Mode=TwoWay}" 
                 ItemsSource="{Binding Path=Sounds}" Grid.Row="1" MinHeight="50" >

However it seems that you are not allowed to set the IsSynchronizedWithCurrentItem to true (that is the one makes sure that current item is synchronized with the source (the viewmodel).

You are allowed to set it to false or null. But they didn’t resolve my problem, that if i changed sound it wasn’t being reflected into the CurrentSound property.

So what to do? When everything else fails, panic!!! No I searched the internet but couldn’t find the problem mentioned. But then it came to me. If I can’t update the source through the xaml. I’m going to have to do it in the code behind, by accessing the Binding for the ListBox and tell it to update its source.

I know for some religious people (MVVM religious people) that is a big crime.  But take a look at what i di

<ListBox x:Name="Sounds" SelectionChanged="Sounds_SelectionChanged" 
                 SelectedItem="{Binding Path=CurrentSound, Mode=TwoWay}" 
                 ItemsSource="{Binding Path=Sounds}" Grid.Row="1" MinHeight="50" >

First of all I removed  IsSynchronizedWithCurrentItem. And I’ve hooked up to the Sounds_SelectionChanged event.

And in the code behind I do the following thing:

private void Sounds_SelectionChanged(object sender, 
            System.Windows.Controls.SelectionChangedEventArgs e)
        {
            BindingExpression binding=Sounds.GetBindingExpression(ListBox.SelectedItemProperty);
            binding.UpdateSource();           
        }

I get the binding expression for the control, and make  call UpdateSource. And we arrive at that precious area I call happy land.

NB! In my opinion this is in no way violating the MVVM principles.

PS. It’s my goal to add some describing how I played the sound in a later post. I might forget it, like a promised blog post  about how to use dynamic (what I aimed at was very similar to Microsoft.Data).

Until then keep on coding in the free world.

Creating a new project based on another project in DTE

by jeppe 27. September 2010 22:47

I’ve been messing around with a little bit of Visual Studio extensibility.  Here is a little snippet of code i used to create a new class library in the solution based on the selected projects.

private void CreateTestProjectForSelectedProjects()
{
    var solution = _applicationObject.Solution as Solution4;
    var activeProjects = _applicationObject.ActiveSolutionProjects as Array;
    foreach (var activeProject in activeProjects)
    {
        var project = activeProject as Project;
        string newProjectName = project.Name + ".Tester";
        string templatePath = solution.GetProjectTemplate("ClassLibrary.zip", "CSharp");

        var path = Path.Combine(Path.GetDirectoryName(solution.FileName), newProjectName);

        solution.AddFromTemplate(templatePath,path, newProjectName, false);
    }
}

Be aware that this code does not currently check if the project it’s trying to create exists.

Ps. Hope this an ok visualization of what I’m aiming at:

image

Remember. Anger, Fear, Agression. The dark side are they

A short post on a TinyMCE issue i had in BlogEngine.net

by jeppe 10. September 2010 00:17

image

I noticed that i was getting a yellow triangle of pending mass destruction

clip_image001

It said that tinyMCE is undefined. After some investigation i found this on the blogengine  forum.

So I searched the source for the page and found this.  

image

I removed it so I could happily return to a little place I call happy land.

Remember: Anger, Fear, Aggression. The dark side are they.

Crm 4.0 Plugins and “An error occured please try again”

by Jeppe 25. February 2010 08:45

Here’s a quick post. If you run into problems when deploying a Plugin to your crm environment and get this message when the plugin should be called (in an update scenario for example):

clip_image001

(English summary: An error occurred

Try to repeat the action)

Here are 2 known (to me) causes for this:

1. Your plugin doesn’t have an empty constructor
2. You haven’t signed the assembly.

Hope this helps. :)

A peek behind the scenes MVC 2 LabelFor, TextboxFor and others.

by jeppe 23. December 2009 00:42

One of the things we got a peek at with MVC Futures when Asp.net mvc 2 was the use of syntax like this in markup (it’s en Expression<Func<TModel,Tvalue>> where TModel is the objecttype to get the value from and TValue is the expected type):

image

Which means that instead of those Harry Potter strings. You use an Expression for determining the name and value.  But like when I eat spicy food it comes with a price. And for this approach it comes with a significant performance penalty http://blog.whiletrue.com/2009/04/aspnet-mvc-performance/ (especially slide nr 25).

I guess that it was one of the main reasons it was in the futures and not in the released version. But they are included in RC and I have been looking through the source code for mvc 2 rc and it seems that the development teem have put some effort into making it more perform better.

What happens is the following (this example is based on the LabelFor but it seems to be the same “general” approach for other extension methods like TextBoxFor, TextAreaFor etc. 

 
public static MvcHtmlString LabelFor<TModel, TValue>(this HtmlHelper<TModel> html, 
    Expression<Func<TModel, TValue>> expression) {
    return LabelHelper(html, 
                       ModelMetadata.FromLambdaExpression(expression, html.ViewData), 
                       ExpressionHelper.GetExpressionText(expression));
}

Two method are called for the last to parameters for the LabelHelper.

1 ModelMetaData.FromLamdaExpression

The Expression and the viewdata is passed in as parameters to the static method FromLamdaExpression which returns a ModelMetadata object.  As the name implies it stores a wide array of metadata related to a model.

The method performs some null checks, redirects to a different method if you reference the same object (model => model). And throws and exception if it’s not a MemberAccess expression (lookup of a value).

Then this happens:

TParameter container = viewData.Model;
Func<object> modelAccessor = () =>
{
    try {
        return CachedExpressionCompiler.Process(expression)(container);
    }
    catch (NullReferenceException) {
        return null;
    }
};

Now the real compilation begins. And this is at least one of the points where performance is taken into consideration. The Process method of the CachedExpressionCompiler goes through three steps to assign the compiled Func to the modelAccessor property as fast as possible. On success it returns the compiled function. Basically this is what happens:

  1. GetFuncFastTrack. It catches simple expression like model => model,  model => 42(constant value), model => StaticClass.Member and model => model.Property. It’s uses a large degree of caches to perform the lookup.
  2. GetFuncFingerprinted. The uses a mechanism where it gets a fingerprint (an id used to identify the signature of an expression) are created and matched against a cache.
  3. GetFuncSlow. (Or the good old fashion Compile call)

The end of the FromLamdaExpression looks like this

MemberExpression memberExpression = (MemberExpression)expression.Body;
string propertyName=memberExpression.Member is PropertyInfo ? memberExpression.Member.Name:null;
Type containerType = memberExpression.Member.DeclaringType;
 
return GetMetadataFromProvider(modelAccessor, typeof(TValue), propertyName, containerType);
 
The short story. modelAccesor, resultype, propertyname and containerType of the property is passed into GetMetadataFromProvider method. Besides the inputted parameter values it further enrich the ModelMetadata object. But that seems be material for completely different blog post.
 

2 ExpressionHelper.GetExpressionText

The second method is the one that generates the Name to be entered

public static string GetExpressionText(LambdaExpression expression) {
    // Crack the expression string for property/field accessors to create its name
    Stack<string> nameParts = new Stack<string>();
    Expression part = expression.Body;
 
    while (part != null) {
        if (part.NodeType == System.Linq.Expressions.ExpressionType.MemberAccess) {
            MemberExpression memberExpressionPart = (MemberExpression)part;
            nameParts.Push(memberExpressionPart.Member.Name);
            part = memberExpressionPart.Expression;
        }
        else {
            break;
        }
    }
 
    // If it starts with "model", then strip that away
    if (nameParts.Count > 0 && String.Equals(nameParts.Peek(), "model", 
               StringComparison.OrdinalIgnoreCase)) {
        nameParts.Pop();
    }
 
    if (nameParts.Count > 0) {
        return nameParts.Aggregate((left, right) => left + "." + right);
    }
 
    return String.Empty;
}

 

 

 

 

It does the following. It creates a stack of string. And as long as the current part isn’t null it' pushes the name of the member to the stack. Lets take this expression. model => model.First.Second.Third.  The first one it will hit is Third. So the stack will look like this at the end:

First
Second
Third.

It then aggregates (join) these together to the composite string.

If the first and only name is model. It’s removed.   I haven’t quite figured that one out yet. It seems be a reserved keyword that you don’t want to use as name in the markup D’oh! It’s the name of the container of ViewData.Model

LabelHelper

The result it that the ModelMetadata and the generated namestring is passed in to the LabelHelper.  Which generates the label.

internal static MvcHtmlString LabelHelper(HtmlHelper html, ModelMetadata metadata, 
          string htmlFieldName) {
    string labelText = metadata.DisplayName ?? metadata.PropertyName ?? htmlFieldName
              .Split('.').Last();
    if (String.IsNullOrEmpty(labelText)) {
        return MvcHtmlString.Empty;
    }
 
    TagBuilder tag = new TagBuilder("label");
    tag.Attributes.Add("for", html.ViewContext.ViewData.TemplateInfo
                .GetFullHtmlFieldId(htmlFieldName));
    tag.SetInnerText(labelText);
    return tag.ToMvcHtmlString(TagRenderMode.Normal);
}

See that if you have used the if DisplayName in the metadata is not null it sets this value to the label (You can set a DisplayName attribute on your objects properties).  This method is internal but it uses a TagBuilder class which on the other hand is public.

public static string GetExpressionText(LambdaExpression expression) {
    // Crack the expression string for property/field accessors to create its name
    Stack<string> nameParts = new Stack<string>();
    Expression part = expression.Body;
 
    while (part != null) {
        if (part.NodeType == System.Linq.Expressions.ExpressionType.MemberAccess) {
            MemberExpression memberExpressionPart = (MemberExpression)part;
            nameParts.Push(memberExpressionPart.Member.Name);
            part = memberExpressionPart.Expression;
        }
        else {
            break;
        }
    }
 
    // If it starts with "model", then strip that away
    if (nameParts.Count > 0 && String.Equals(nameParts.Peek(), "model",           
              StringComparison.OrdinalIgnoreCase)) {
        nameParts.Pop();
    }
 
    if (nameParts.Count > 0) {
        return nameParts.Aggregate((left, right) => left + "." + right);
    }
 
    return String.Empty;
}

The last thing to take notice of is the MvcHtmlString being returned by the LabelHelper. Here's the information copied directly from the comments, but basically you should use this if create any kind of helper or extensionmethod that can be used in the view:

// In ASP.NET 4, a new syntax <%: %> is being introduced in WebForms pages, where <%: expression %> is equivalent to
// <%= HttpUtility.HtmlEncodeexpression) %>. The intent of this is to reduce common causes of XSS vulnerabilities
// in WebForms pages (WebForms views in the case of MVC). This involves the addition of an interface
// System.Web.IHtmlString and a static method overload System.Web.HttpUtility::HtmlEncode(object).  The interface
// definition is roughly:
//   public interface IHtmlString {
//     string ToHtmlString();
//   }
// And the HtmlEncode(object) logic is roughly:
//   - If the input argument is an IHtmlString, return argument.ToHtmlString(),
//   - Otherwise, return HtmlEncode(Convert.ToString(argument)).
//
// Unfortunately this has the effect that calling <%: Html.SomeHelper() %> in an MVC application running on .NET 4
// will end up encoding output that is already HTML-safe. As a result, we're changing out HTML helpers to return
// MvcHtmlString where appropriate. <%= Html.SomeHelper() %> will continue to work in both .NET 3.5 and .NET 4, but
// changing the return types to MvcHtmlString has the added benefit that <%: Html.SomeHelper() %> will also work
// properly in .NET 4 rather than resulting in a double-encoded output. MVC developers in .NET 4 will then be able
// to use the <%: %> syntax almost everywhere instead of having to remember where to use <%= %> and where to use
// <%: %>. This should help developers craft more secure web applications by default.
// To create an MvcHtmlString, use the static Create() method instead of calling the protected constructor
That’s all for now. I wish you a merry christmas. 
And as always remember to stay clear of the dark side of the force

NHibernate version conflict

by jeppe 19. December 2009 00:16

I regularly encounter this exception. In many examples it occurs when working with Nhibernate image

It’s actually pretty easy to solve if you now what to do. You have to add the following to your appconfig or your webconfig:

<runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">        
    <dependentAssembly>
      <assemblyIdentity name="NHibernate" publicKeyToken="AA95F207798DFDB4" culture="neutral"/>
      <bindingRedirect oldVersion="0.0.0.0-2.1.2.4000" newVersion="2.1.2.4000"/>
    </dependentAssembly>
  </assemblyBinding>
</runtime>

In many cases when this happens you will get a warning when you compile. If you double click the specific warning. Visual Studio will try to generate the above code in your config file. It doesn’t always work, but it’s still pretty cool.

That’s all for now and remember

Only a sith deals in absolutes

Flush in Nhibernate

by jeppe 17. December 2009 22:18

This is a short post that falls under the category. Future lookup for me. The past year I have worked a lot with Nhibernate. In my opinion it’s the closest you come to a perfect Object Relational Mapper. But besides getting the hang of how to handle the ISession (“basically” the unit of work)  one thing i constantly forget is what precisely what Flush does. From the intellisense they pull a “Microsoft documentation” on me.

 image 

Well almost. Ps by Microsoft Documentation. F.ex:  object.DoSomethingStrange() (“Will do something strange”). Well I’m pretty sure most people now what Flush does. But here goes based on the documentation:

Short Version: Flush will synchronize the changes you have made to the ISession object you are working on. Meaning that some calls will be made to the database (select insert etc.).  So it’s roughly: ExecuteTheRelevantSqlBasedOnPreviousOperations() .

You will most likely not need to call Flush() as it is handled automatically for you during your operations. Most query operations will automatically perform the flush. if you wrap a using around a ITransaction. Flush will automatically be called.

Thanks for your time.

remember: Stay away from the dark side of the force

Using the new dynamic keyword (prelude to upcoming post)

by Jeppe 3. December 2009 13:43

One of the new things being introduced with .net 4.0 is the dynamic keyword. And it serves as a good entry point to calling dynamic languages such as iron python and iron ruby or situations where a static approach is troublesome.

I’m basically more of static language guy than a dynamic language guy. But I must admit if used for good the dynamic features has some potential.

I’m planning a post where I’ll show an example of using it for reading values from f.ex a SqlDataReader in a very easy fashion. This post serves as a prelude to that one. With a short introduction to the dynamic keyword.

The dynamic keyword

Before i continue lets shortly examine what the dynamic keyword is with this short and rude example.

 public class YoungChildClass
    {
        public string DoSomethingEvil()
        {
            return "Bully a child";
        }
    }
 
    public struct SithClass
    {
        public string DoSomethingEvil()
        {
            return "Kill jedis";
        }
    }

Here we have two classes simulating two kind of persons, for whom evil comes naturally. A YoungChildClass and a SithClass (Shame on you).

They are not connected through any interface (IEvilDoer) or inheritance (BaseOfEvil) though. So if you wanted you couldn’t immediately create a shared method that would call the DoSomethingEvil method without using some kind of reflection or spliting it up:

public static void DoEvilThing(YoungChildClass knownEvilDoer)
{
    Console.WriteLine(knwonEvilDoer.DoSomethingEvil());
}
 
public static void DoEvilThing(SithClass knownEvilDoer)
{
    Console.WriteLine(knwonEvilDoer.DoSomethingEvil());
}

In comes the dynamic keyword that lets you do that very easily. I can instantiate my evilDoer as dynamic. When I’m using the dynamic keyword I can call whatever method I want to.

static void Main(string[] args)
{
    dynamic evilDoer = new YoungChildClass();
    Console.WriteLine(evilDoer.DoSomethingEvil());
  
    DoEvil(new SithClass());
}
 
private static void DoEvil(dynamic evilDoer)
{
    Console.WriteLine(evilDoer.DoSomethingEvil());
}

I can initialize the YoungChildClass as a dynamic and call DoSomethingEvil(). Or pass any arbitrary object to the DoEvil method.

I could even go apeshit insane and call:

evilDoer.MakeBakedPotatoesAndStuffedBananas()

And the compiler wouldn’t complain. Because the evilDoer object is declared dynamic, so it won’t check if the actual method is there at compile. But if i ran the program it would fail because none of the classes have the insanity method on them.

image

But look at all the information you get (besides the insight in the programmers mental state).  This is not an Object Reference not set to an instance of an object (I think I’ll dedicate a complete blog post ranting about uninformative exceptions).

Another thing you don’t get is intellisense. The object is dynamic so even though I’ve initialized a known object (YoungChildClass) I have to know which method to call. If you look at the DoEvil method this will make more sense.

Is this basically a prettier way to do magic strings?

Hell yeah! But it is also much more than that. As i mentioned in the introduction to this blog post, It is something that can be used when calling dynamic languages. I really haven’t played around with that part very much, so I won’t dig into that in this post. But without dynamic you would have to write code that could be really nasty to look at.

And that brings me forward to one of the major advantages of the dynamic keyword. It can make calling non static typed object much prettier and easier. Especially the scenarios that would involve a lot like this:

int? result = reader["Years"].Value == DBNull.Value ? null : reader["Years"].Value;

It Can be solved much prettier. But that is the topic of the upcoming blog post. This will also provide a more concrete example of dynamic, compared to this more or less obscure example. (I myself prefer concrete examples)

PS. The dynamic keyword is just the tip of the iceberg. So go look around the net and learn more about it. You will most likely come across that strangely named class ExpandoObject.

May the force be with you!

Tags: , ,

About the author

My name is Jeppe Vammen Kristensen. I live and work in Århus as a .net developer for Vertica A/S

Page List