got net?

Kevin Hazzard's Brain Spigot

About the author

Welcome to Kevin Hazzard's blog.
E-mail me Send mail

Recent comments

Authors

Disclaimer

The opinions expressed herein are my own personal opinions and do not represent my employer's view in anyway.

© Copyright 2009

MSDN Roadshow - What's New in Silverlight 2?

Here are my slides and sample code from the presentation I did on November 20, 2008 in Hampton, Virginia.

MSDNRoadshowSilverlightDemos20081120.zip (2.82 mb)

Whats new in Silverlight .pptx (5.80 mb)

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Posted by kevin on Thursday, November 20, 2008 7:02 PM
Permalink | Comments (1) | Post RSSRSS comment feed

The Missing System.Dynamic.DynamicObject Class

If you've got a copy of the Visual Studio 2010 CTP and you've been watching the presentations done by Anders Hejlsberg and Jim Hugunin at the Microsoft Professional Developer's Conference 2008, you may be wondering where the DynamicObject class is. It's not in the CTP. If you snoop around in the System.Scripting.Actions namespace, you'll find some of the required pieces but the actual DynamicObject class used in the demos just isn't there.

There's nothing magical about the DynamicObject class. It's a pretty simple IDynamicObject implementation that maps calls through the MetaObject for the DynamicObject as follows:

  • MetaObject.GetMember => DynamicObject.GetMember
  • MetaObject.SetMember => DynamicObject.SetMember
  • MetaObject.Invoke => DynamicObject.Invoke
  • MetaObject.Call => DynamicObject.InvokeMember

Of couse, these little "dispatchers" just set up the expression tree tests and targets as Jim described in his talk. Curt Hagenlocher was kind enough to provide a copy of the DynamicObject source code which can be found here. Thanks, Curt! I've also included the source code here, too. If you include this class in your project, the VS2010 CTP demos that Anders and Jim showed at PDC2008 will work just fine.

/* ****************************************************************************
 *
 * Copyright (c) Microsoft Corporation. 
 *
 * This source code is subject to terms and conditions of the Microsoft Public License. A 
 * copy of the license can be found in the License.html file at the root of this distribution. If 
 * you cannot locate the  Microsoft Public License, please send an email to 
 * dlr@microsoft.com. By using this source code in any fashion, you are agreeing to be bound 
 * by the terms of the Microsoft Public License.
 *
 * You must not remove this notice, or any other, from this software.
 *
 *
 * ***************************************************************************/

using System;
using System.Collections.Generic;

using System.Linq.Expressions;
using System.Scripting.Actions;

namespace System.Dynamic {
    public class DynamicObject : IDynamicObject {
        public virtual object GetMember(GetMemberAction info) {
            throw new MissingMemberException("Dynamic", info.Name);
        }
        public virtual void SetMember(SetMemberAction info, object value) {
            throw new MissingMemberException("Dynamic", info.Name);
        }

        public virtual object Invoke(InvokeAction info, object[] arguments) {
            throw new NotImplementedException("Invoke");
        }

        public virtual object InvokeMember(CallAction info, object[] arguments) {
            throw new NotImplementedException("InvokeMember");
        }

        public MetaObject GetMetaObject(Expression parameter) {
            return new DynamicMetaObject(this, parameter);
        }

        class DynamicMetaObject : MetaObject {
            public DynamicMetaObject(DynamicObject v, Expression e) : base(e, Restrictions.Empty, v) { }

            public override MetaObject GetMember(GetMemberAction info, MetaObject[] args) {
                var x = this.Expression;
                var test = Expression.TypeIs(x, typeof(DynamicObject));
                var target = Expression.Call(
                                  Expression.Convert(x, typeof(DynamicObject)),
                                  typeof(DynamicObject).GetMethod("GetMember"),
                                  Expression.Constant(info));
                return new MetaObject(target, Restrictions.ExpressionRestriction(test));
            }

            public override MetaObject SetMember(SetMemberAction info, MetaObject[] args) {
                var x = this.Expression;
                var y = args[1].Expression;
                var test = Expression.TypeIs(x, typeof(DynamicObject));
                var target = Expression.Call(
                    Expression.Convert(x, typeof(DynamicObject)),
                    typeof(DynamicObject).GetMethod("SetMember"),
                    Expression.Constant(info),
                    Expression.ConvertHelper(y, typeof(object)));
                return new MetaObject(target, Restrictions.ExpressionRestriction(test));
            }

            public override MetaObject Invoke(InvokeAction action, MetaObject[] args) {
                var x = this.Expression;
                var test = Expression.TypeIs(x, typeof(DynamicObject));
                var inits = new Expression[args.Length - 1];
                for (int i = 0; i < inits.Length; i++) {
                    inits[i] = Expression.ConvertHelper(args[i + 1].Expression, typeof(object));
                }
                var argsArray = Expression.NewArrayHelper(typeof(object), inits);
                var target = Expression.Call(
                    Expression.Convert(x, typeof(DynamicObject)),
                    typeof(DynamicObject).GetMethod("Invoke"),
                    Expression.Constant(action), argsArray);
                return new MetaObject(target, Restrictions.ExpressionRestriction(test));
            }

            public override MetaObject Call(CallAction action, MetaObject[] args) {
                var x = this.Expression;
                var test = Expression.TypeIs(x, typeof(DynamicObject));
                var inits = new Expression[args.Length - 1];
                for (int i = 0; i < inits.Length; i++) {
                    inits[i] = Expression.ConvertHelper(args[i + 1].Expression, typeof(object));
                }
                var argsArray = Expression.NewArrayHelper(typeof(object), inits);
                var target = Expression.Call(
                    Expression.Convert(x, typeof(DynamicObject)),
                    typeof(DynamicObject).GetMethod("InvokeMember"),
                    Expression.Constant(action), argsArray);
                return new MetaObject(target, Restrictions.ExpressionRestriction(test));
            }
        }
    }
}

Currently rated 5.0 by 1 people

  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Posted by kevin on Tuesday, November 11, 2008 7:04 PM
Permalink | Comments (1) | Post RSSRSS comment feed

Mixing Static & Dynamic .NET Languages - November 2008 Update

This is the November 2008 update of my now famous "Mixing Static & Dynamic .NET Languages" presentation. OK, so it's not a famous talk. But it still rocks and the folks at the code camps love it. This is the material I will be using at my talk at the upcoming Raleigh Code Camp on 11/15/2008. The source code and slides are attached below. When you run the demo code, you'll see a dialog that looks like this: 

The application, written primarily in C#, implements a shopping cart to which various products can be added. The shopping cart isn't the cool part, of course. What's interesting is the use of Python code to implement the discounting/marketing rules within the cart. If you press the Show Rules Editor button at the top of the form, you'll see the rule editor dialog: 



Python code is pretty easy to read isn't it? You can probably follow the logic to see that if certain counts of Entertainment products are added, they get discounted at various levels. And a trigger is set on the total count of items in the cart, too. There's a bug in the code though. But that's part of the demo. Can you find the bug?

Hopefully, if you run this code and understand it, you mind will be expanded a bit. One of the most often asked questions I get when talking about IronPython is, "How do I convince my boss to let me write that application in Python?" My answer is, "You don't have to write the whole thing in Python. With the fantastically rich hosting APIs in the .NET Dynamic Language Runtime (DLR), you can write the portions that need dynamism in Python and write the rest in C# or VB.NET." In fact, for most applications, the portion that can benefit from dynamic behavior is usually fairly small as a percentage of the application's total surface area. So this model of mixing static and dynamic languges is a nice approach to those kinds of problems.

Slides for MixingStaticAndDynamicDotNETLanguages 20081115.pptx (251KB)

Source Code for MixingStaticAndDynamicLanguagesInDotNet 20081109 (43KB)

Currently rated 5.0 by 1 people

  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Posted by kevin on Friday, November 07, 2008 5:17 PM
Permalink | Comments (3) | Post RSSRSS comment feed

Directories of PDC2008 Content

Mike Swanson, a Microsoft Technical Evangelist, has published a great directory of the Microsoft Professional Developer Conference 2008 content on Channel 9. Very nice rollup. Check it out.

My Brazilian friend Luciano Guerche published another directory to PDC2008 content orgnized by the days on which they were delivered at these locations on his blog:

Day 1 - http://weblogs.asp.net/guerchele/archive/2008/10/29/pdc-2008-day-1-46-matching-sessions.aspx
Day 2 - http://weblogs.asp.net/guerchele/archive/2008/10/29/pdc-2008-day-2-50-matching-sessions.aspx
Day 3 - http://weblogs.asp.net/guerchele/archive/2008/10/29/pdc-2008-day-3-60-matching-sessions.aspx
Day 4 - http://weblogs.asp.net/guerchele/archive/2008/10/29/pdc-2008-day-4-49-matching-sessions.aspx

 

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags:
Categories: General
Posted by kevin on Tuesday, November 04, 2008 12:39 PM
Permalink | Comments (0) | Post RSSRSS comment feed

Enable Windows 7 Flashy Features

If you were at the Microsoft Professional Developers Conference 2008 (PDC2008), you got a copy of Windows 7 pre-beta to install. However, if you installed it, you might have been upset to find that a lot of the cool features shown in the keynote address were disabled. I'm not sure why Microsoft did this but Rafael Rivera, Jr. has hacked the features back on. I am not a fan of nasty hacks like this but it is pre-beta software after all. Jump to Rafael's blog post to download the tool and read the instructions.

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags:
Categories: General | Windows 7
Posted by kevin on Monday, November 03, 2008 12:44 PM
Permalink | Comments (1) | Post RSSRSS comment feed