Part 3: Adding a dynamic decorator to an object – the “Why not”

by Tobias Hertkorn on December 21st, 2009

Krzysztof pointed me to his post Castle Dynamic Proxy FAQ: why there’s no “class proxy with target” why the dynamic decorator is not part of Castles’s DynamicProxy implementation yet.

Looking at the code one realizes that the real problem is, that IsAdult() is not virtual. That’s why the decorator is not able to intercept and redirect that call to the target. There is no way around it – that is a real bug and it does show why a class proxy with a target is indeed dangerous. Thanks for pointing it out to me, Krzysztof!

The question we have to ask now is: If we refuse to generate the proxy, if any member more visible than protected is non-virtual, would that get rid of the bug? I would argue that it will, since the proxy will now be able to redirect the call to the target and everything works out fine. Or am I again missing something?

Post to Twitter Tweet this

December 21st, 2009 6:44 pm | Comments (0)

Part 2: Adding a dynamic decorator to an object – the “Why”

by Tobias Hertkorn on December 20th, 2009

I got the question "Why would we do that, we can't guarantee that nobody would use the original reference to manipulate stuff."

Well, this question is answered best by an example.

Imagine an object with a complicated creation and/hydration path. We are in a multithreaded environment and the object is passed between theads often, etc. There are to approaches to ensure that on has no data corruption because of multi threading. Either locking or immutability. Immutability is a strong feature but usually it is quite clumsy to use. Especially since with purely immutable objects there can be a lot of memory pressure with all the copying and creating of objects. Think "creating a complex immutable tree".

A solution to circumvent the memory pressure is to have a mutable object during creation and marking it as immutable after it is fully hydrated. This usually leads in C# to code similar to this:

C#:
  1. public class MyImmutable
  2. {
  3.     private string m_property;
  4.     public string Property
  5.     {
  6.         get { return m_property; }
  7.         set
  8.         {
  9.             if (m_immutable) { throw new MemberAccessException("Type is marked as immutable"); }
  10.             m_property = value;
  11.         }
  12.     }
  13.  
  14.     private bool m_immutable = false;
  15.     public void MarkAsImmutable()
  16.     {
  17.         m_immutable = true;
  18.     }
  19. }
  20.  
  21. public class MyImmutableFactory
  22. {
  23.     public MyImmutable CreateMyImmutable()
  24.     {
  25.         MyImmutable myImmutable = new MyImmutable();
  26.         myImmutable.Property = "Test";
  27.  
  28.         myImmutable.MarkAsImmutable();
  29.  
  30.         return myImmutable;
  31.     }
  32. }
  33.  
  34. public static class ImmutableOldStyleTest
  35. {
  36.     public static void Test()
  37.     {
  38.         MyImmutableFactory myImmutableFactory = new MyImmutableFactory();
  39.         MyImmutable myImmutable = myImmutableFactory.CreateMyImmutable();
  40.  
  41.         bool caughtException = false;
  42.         try
  43.         {
  44.             myImmutable.Property = "Test2";
  45.         }
  46.         catch (MemberAccessException)
  47.         {
  48.             caughtException = true;
  49.         }
  50.  
  51.         Debug.Assert(caughtException);
  52.         Debug.Assert(myImmutable.Property == "Test");
  53.     }
  54. }

For each set it is the programmer's resposibility to check within the setter, if it may or may not proceed with the setting of the value. Which can be quite tiring for multiple properties (DRY for the check!) and multiple immutable types (DRY for the MarkAsImmutable() method).

An alterative approach would be to use a decorator:

C#:
  1. public class ImmutableInterceptor : IInterceptor<MyType>
  2. {
  3.     public void InterceptGetter(IProxy proxy, MyType @object, string propertyName, out object value)
  4.     {
  5.         proxy.ProceedGetter(propertyName, out value);
  6.     }
  7.  
  8.     public void InterceptSetter(IProxy proxy, MyType @object, string propertyName, object value)
  9.     {
  10.         throw new MemberAccessException("Type is marked as immutable");
  11.     }
  12. }
  13.  
  14. public class MyTypeFactory
  15. {
  16.     public MyType CreateMyType()
  17.     {
  18.         MyType myType = new MyType();
  19.         myType.Property = "Test";
  20.  
  21.         return MarkAsImmutable(myType);
  22.     }
  23.  
  24.     private MyType MarkAsImmutable(MyType myType)
  25.     {
  26.         ImmutableInterceptor immutableInterceptor = new ImmutableInterceptor();
  27.  
  28.         return GenerateProxy(myType, immutableInterceptor);
  29.     }
  30.  
  31.     // This method belongs in a proxy generator
  32.     private static MyType GenerateProxy(MyType myType, IInterceptor<MyType> interceptor)
  33.     {
  34.         return new MyTypeProxy(myType, interceptor);
  35.     }
  36. }
  37.  
  38. public static class ImmutableTest
  39. {
  40.     public static void Test()
  41.     {
  42.         MyTypeFactory myTypeFactory = new MyTypeFactory();
  43.         MyType myType = myTypeFactory.CreateMyType();
  44.  
  45.         bool caughtException = false;
  46.         try
  47.         {
  48.             myType.Property = "Test2";
  49.         }
  50.         catch (MemberAccessException)
  51.         {
  52.             caughtException = true;
  53.         }
  54.  
  55.         Debug.Assert(caughtException);
  56.         Debug.Assert(myType.Property == "Test");
  57.     }
  58. }

Way more straight forward, isn't it?

Another application could be the old INotifyPropertyChanged problem, read-only collections, ...

Post to Twitter Tweet this

December 20th, 2009 6:03 pm | Comments (0)

Adding a dynamic decorator to an object

by Tobias Hertkorn on December 19th, 2009

I am really confused that non of the dynamic proxy frameworks out there allow me to add dynamic behavior after the fact - I have an instantiated object and need to add behavior when a property is accessed. Like this:

C#:
  1. var myType = new MyType();
  2. myType.Property = "Test";
  3.  
  4. var interceptor = new MyInterceptor();
  5. MyType wrappedMyType = proxyGenerator.GenerateProxy(myType, interceptor);
  6. wrappedMyType.Property = "Test2";
  7.  
  8. Debug.Assert(myType.Property == "Test2");
  9. Debug.Assert(interceptor.SetterWasCalled);

All current frameworks need me to instantiate the object using the proxy generator. Which is unfortunate, because, unlike in the example, I plan to introduce the decorator in a part of my application that is conceptionally in a completely different region of the application's source code. It would just not make sense to introduce the knowledge about the additional behavior at the point of object creation.

It should be fairly easy to pull off, since I am already able to do it by hand:

C#:
  1. public class MyInterceptor : IInterceptor<MyType>
  2. {
  3.     public void InterceptGetter(IProxy proxy, MyType @object, string propertyName, out object value)
  4.     {
  5.         // do something before get
  6.         proxy.ProceedGetter(propertyName, out value);
  7.         // do something after get
  8.     }
  9.  
  10.     public void InterceptSetter(IProxy proxy, MyType @object, string propertyName, object value)
  11.     {
  12.         // do something before set
  13.         proxy.ProceedSetter(propertyName, value);
  14.         // do something after set
  15.         m_setterCalled = true;
  16.     }
  17.  
  18.     private bool m_setterCalled = false;
  19.     public bool SetterWasCalled
  20.     {
  21.         get { return m_setterCalled; }
  22.     }
  23. }
  24.  
  25. public class MyType
  26. {
  27.     public virtual string Property { get; set; }
  28. }
  29.  
  30. /////// AUTOGENERATED PROXY ///////
  31.  
  32. public class MyTypeProxy : MyType, IProxy
  33. {
  34.     private MyType m_object;
  35.     private IInterceptor<MyType> m_interceptor;
  36.  
  37.     public MyTypeProxy(MyType @object, IInterceptor<MyType> interceptor)
  38.     {
  39.         m_object = @object;
  40.         m_interceptor = interceptor;
  41.     }
  42.  
  43.     public override string Property
  44.     {
  45.         get
  46.         {
  47.             object value;
  48.             m_interceptor.InterceptGetter(this, m_object, "Property", out value);
  49.             return (string)value;
  50.         }
  51.         set { m_interceptor.InterceptSetter(this, m_object, "Property", value); }
  52.     }
  53.  
  54.     public void ProceedGetter(string propertyName, out object value)
  55.     {
  56.         if (propertyName == "Property")
  57.         {
  58.             value = m_object.Property;
  59.         }
  60.         else
  61.         {
  62.             throw new MissingMemberException();
  63.         }
  64.     }
  65.  
  66.     public void ProceedSetter(string propertyName, object value)
  67.     {
  68.         if (propertyName == "Property")
  69.         {
  70.             m_object.Property = (string)value;
  71.         }
  72.         else
  73.         {
  74.             throw new MissingMemberException();
  75.         }
  76.     }
  77. }
  78.  
  79. /////// SUPPORTING CODE ///////
  80.  
  81. public interface IProxy
  82. {
  83.     void ProceedGetter(string propertyName, out object value);
  84.     void ProceedSetter(string propertyName, object value);
  85. }
  86.  
  87. public interface IInterceptor<T>
  88. {
  89.     void InterceptGetter(IProxy proxy, T @object, string propertyName, out object value);
  90.     void InterceptSetter(IProxy proxy, T @object, string propertyName, object value);
  91. }
  92.  
  93. /////// TEST ///////
  94.  
  95. public static class Test
  96. {
  97.     public static void ProxyTest()
  98.     {
  99.         var myType = new MyType();
  100.         myType.Property = "Test";
  101.  
  102.         var interceptor = new MyInterceptor();
  103.         MyType wrappedMyType = GenerateProxy(myType, interceptor);
  104.         wrappedMyType.Property = "Test2";
  105.  
  106.         Debug.Assert(myType.Property == "Test2");
  107.         Debug.Assert(interceptor.SetterWasCalled);
  108.     }
  109.  
  110.     // This method belongs in a proxy generator
  111.     private static MyType GenerateProxy(MyType myType, IInterceptor<MyType> interceptor)
  112.     {
  113.         return new MyTypeProxy(myType, interceptor);
  114.     }
  115. }

Who will help me to adapt the API to the Castle DynamicProxy API and to write the actual proxy/decorator generation? :)

Post to Twitter Tweet this

December 19th, 2009 6:01 pm | Comments (2)

Silverlight 4 Beta released

by Tobias Hertkorn on November 18th, 2009

AWESOME. This just made my day:

Silverlight 4 beta

This sounds like a great release that smoothes the edges around ADO, out of browser and code reuse between WPF and Silverlight. That's HUGE!

Plus PRINTING! Finally. And the mic and webcam features are nothing to sneeze at either. The list goes on and on. Seriously, they really packed a lot of stuff in. And it seems to be all community feedback driven. They really listened to us over at uservoice. 8 out of the top 10 features actually made it into that release. Great work!

Enjoy!

Post to Twitter Tweet this

November 18th, 2009 9:35 pm | Comments (0)

Bootstrapping easy_install for python 2.6 on Windows

by Tobias Hertkorn on September 4th, 2009

I had to setup Python 2.6 on Windows. And of course I wanted to use the magnificent Setuptools, specifically easy_install. Unfortunatelly there is only an msi for 2.5 on the website. But actually bootstrapping the 2.6 egg is not that hard:

Download the 2.6 egg from the setuptools download site. Put it in a temporary directory like c:\downloads\setuptools. Then unzip the egg to the same folder.

Open a command line, go to c:\downloads\setuptools and use the following command:


python -c "import sys; sys.path.insert(0, 'C:/Downloads/setuptools/setuptools-0.6c9-py2.6.egg'); from setuptools.command.easy_install import bootstrap; sys.exit(bootstrap())"

That should be it.

Post to Twitter Tweet this

September 4th, 2009 2:49 pm | Comments (2)

C# is not (yet) a high perf language

by Tobias Hertkorn on August 2nd, 2009

Disclamer: The lcg used in this article has drawbacks but it was sufficiently random for my purposes. Please be sure to check if that assumption holds for you as well before using!

Well, this won't come to you as a shocker - but C# is not a high performance language... No, wrong, the C# compiler is not primarily optimized for performance. I noticed it while playing around with a linear congruential generator, a fast and lightweight pseudo random generator.

The lcg is in essence this code fragment:

C#:
  1. PRN = (A * PRN + C) % M; // [0;M[

which generates the next pseudo random number (PRN) which is a number between 0 and M (0 inclusive, M exclusive), using carefully chosen constants A, C and M.

In order to generate a double between 0 and max the naive way to do so is like this:

C#:
  1. private static double RandomLcg(double max)
  2. {
  3.    PRN = (A * PRN + C) % M; // [0;M[
  4.    return max * PRN / M;
  5. }

Now what would you say, if I told you that this optimization, no not optimization - reordering,

C#:
  1. private static double RandomLcg(double max)
  2. {
  3.    PRN = (PRN * A + C) % M; // [0;M[
  4.    return max * (PRN * (1.0 / M));
  5. }

is almost TWICE at fast as the original? Curious, isn't it?!

The fun part is - manually inlining the PRN write and access gives another 10% improvement. So the final version

C#:
  1. private static double RandomLcg(double max)
  2. {
  3.    return max * ((PRN = (PRN * A + C) % M) * (1.0 / M));
  4. }

generates 1,000,000,000 pseudo numbers in 11,4 seconds on my machine - the original version needs 20,7 seconds.

This kind of performance improvement is not uncommon in any language, but especially the manual inlining surprised me. I guess it is a sign that the compiler team is - understandibly - focusing on other things than extracting the last bit of performance from C#. After all, who needs to regularly generate a billion PRNs using C#?

Download source for crude test program.

Post to Twitter Tweet this

August 2nd, 2009 6:57 pm | Comments (3)

Optimizing heavy arithmetics in Mono

by Tobias Hertkorn on June 29th, 2009

Sowhat as a tribute to this rather foolish letter.

---

This will be an article about how I optimized the md5 algorithm in Mono and the Microsoft .NET Framework. I haven't completed it yet, but there is quite a bit about optimization in my blog. Check out all the mentions of md5 in my blog for some pointers.

If you need my work on this right now, raw and unpolished - please feel free to email me at tobias at hertkorn dot com. Or to get some hand-on example, go to my post about the optimized Md5CryptoServiceProvider in mono.

Optimizing the md5 algo on little endian machines

This decoding step is a major part within the md5 algo. It translates a 64 byte array into a 16 uint array. The general endian-safe step looks like this:

C#:
  1. for (i = 0; i <16; i++)
  2. {
  3.   buff[i] = (uint)(inputBuffer[inputOffset + 4 * i])
  4.     | (((uint)(inputBuffer[inputOffset + 4 * i + 1])) <<8 )
  5.     | (((uint)(inputBuffer[inputOffset + 4 * i + 2])) <<16)
  6.     | (((uint)(inputBuffer[inputOffset + 4 * i + 3])) <<24);
  7. }

If this step is performed on a little endian machine, the bytes are already safed in memory in the right order and there is no need for all the bitlogic. Therefore optimizing it using unsafe code and direct copying 4 consecutive bytes as one uint gives a huge speed increase:

C#:
  1. unsafe
  2. {
  3.   fixed (byte* bFixed = inputBuffer)
  4.   {
  5.     byte* inputPointer = bFixed + inputOffset;
  6.  
  7.     for (i = 0; i <16; i++)
  8.     {
  9.       buff[i] = *(uint*)(inputPointer);
  10.       inputPointer += 4;
  11.     }
  12.   }
  13. }

As we are already in unsafe context using an additional pointer for buff gives an additional speed increase:

C#:
  1. unsafe
  2. {
  3.   fixed (byte* bFixed = inputBuffer)
  4.   {
  5.     fixed (uint* aFixed = buff)
  6.     {
  7.       byte* inputPointer = bFixed + inputOffset;
  8.       uint* bufferPointer = aFixed;
  9.  
  10.       for (i = 0; i <16; i++)
  11.       {
  12.         *bufferPointer = *(uint*)(inputPointer);
  13.         inputPointer += 4;
  14.         bufferPointer++;
  15.       }
  16.     }
  17.   }
  18. }

Be sure to still make this Md5 implementation endian safe by introducing a if:

C#:
  1. if (BitConverter.IsLittleEndian)
  2. {
  3.   // unsafe decode
  4. }
  5. else
  6. {
  7.   // bitshifting decode
  8. }

Avoiding unnecessary stloc and ldloc ops

If possible do as much arithmetic as possible in one go. For example:

C#:
  1. b += (((d ^ a) & c) ^ a) + (uint)K[7] + buff[7];
  2. b = (b <<22) | (b>> 10);
  3. b += c;

This b += c is not smart to use in this situation and actually produces a performance hit. Better would be:

C#:
  1. b += (((d ^ a) & c) ^ a) + (uint)K[7] + buff[7];
  2. b = ((b <<22) | (b>> 10)) + c;

Altering the whole segment like this in the md5 algorithm adds up to a 10-15% performance increase!

Let's look at the IL:

IL:
  1. ldloc.1
  2. ldloc.3
  3. ldloc.0
  4. xor
  5. ldloc.2
  6. and
  7. ldloc.0
  8. xor
  9. ldsfld unsigned int32[] MD5CryptoServiceProviderMonoOrig::K
  10. ldc.i4.7
  11. ldelem.u4
  12. add
  13. ldarg.0
  14. ldfld unsigned int32[] MD5CryptoServiceProviderMonoOrig::buff
  15. ldc.i4.7
  16. ldelem.u4
  17. add
  18. add
  19. stloc.1
  20. ldloc.1
  21. ldc.i4.s 22
  22. shl
  23. ldloc.1
  24. ldc.i4.s 10
  25. shr.un
  26. or
  27. stloc.1  // stores b
  28. ldloc.1  // loads b
  29. ldloc.2
  30. add
  31. stloc.1

the second version's:

IL:
  1. ldloc.1
  2. ldloc.3
  3. ldloc.0
  4. xor
  5. ldloc.2
  6. and
  7. ldloc.0
  8. xor
  9. ldsfld unsigned int32[] MD5AddOptimization3::K
  10. ldc.i4.7
  11. ldelem.u4
  12. add
  13. ldarg.0
  14. ldfld unsigned int32[] MD5AddOptimization3::buff
  15. ldc.i4.7
  16. ldelem.u4
  17. add
  18. add
  19. stloc.1
  20. ldloc.1
  21. ldc.i4.s 22
  22. shl
  23. ldloc.1
  24. ldc.i4.s 10
  25. shr.un
  26. or
  27.                // store, load eliminated
  28. ldloc.2
  29. add
  30. stloc.1

Post to Twitter Tweet this

June 29th, 2009 8:38 pm | Comments (0)

Version 1.2.1 of Hg Commit Monitor released

by Tobias Hertkorn on June 29th, 2009

Just finished a new version of Hg Commit Monitor. This version now includes ssh support, additional error handling and prevents a bug in the atom exporter of hgweb from influencing the updates. Enjoy.

Please leave a comment if I should follow Richard Stallman's plea to drop C# for Hg Commit Monitor - and rewrite the whole thing in say ... vb?

Post to Twitter Tweet this

June 29th, 2009 1:32 am | Comments (0)

Stylishly improving Silverlight Toolkit Chart’s Performance

by Tobias Hertkorn on June 27th, 2009

TL;TR: Skip all the way down and download the complete style without "Show" storyboard for the Silverlight Toolkit March 2009 release.

I am currently looking at a couple of Silverlight features and extensions. And what's about the first thing one wants to see - GRAPHS. Well, that's me at least - maybe my background in Physics does push me in weird ways most of the times sometimes...

What I found was that the performance of the charts is not that great - when going to more than a couple datapoints ... to say like 1000?! :-D Oh, and of course those datapoints should change all the time, right? Turns out that does kinda have some impact on performance - since every single datapoint has an animation attached to it when it gets shown or hidden.

I am a total noob when it comes to XAML in general and Silverlight in particular - so it was a huge break-through for me to find out that one can change the style of existing controls. Yeah I know. Knocked me out though. So I got the trial of Expressoin Blend 2, did all the steps that were necessary to get to the templates. And found out that now all my datapoints where bright orange. Umm, that's not fun.

So after a bit more of fumbling around I found out that it's all very easy - when one knows how to do it... I know this is one of the "aha, actually he is not that bright" kinda revelation blog posts. ;) Aaaanyway.

The new template for a datapoint (in this particular case a LineDataPoint for LineSeries) that has no fade in translation looks like this:

XML:
  1. <ControlTemplate TargetType='charting:LineDataPoint' x:Key='LineNoTransition'>
  2.   <Grid Opacity='1' x:Name='Root'>
  3.     <vsm:VisualStateManager.VisualStateGroups>
  4.       <vsm:VisualStateGroup x:Name='CommonStates'>
  5.         <vsm:VisualStateGroup.Transitions>
  6.           <vsm:VisualTransition GeneratedDuration='0:0:0.1' />
  7.         </vsm:VisualStateGroup.Transitions>
  8.         <vsm:VisualState x:Name='Normal' />
  9.         <vsm:VisualState x:Name='MouseOver'>
  10.           <Storyboard>
  11.             <ColorAnimationUsingKeyFrames BeginTime='00:00:00' Duration='00:00:00.0010000' Storyboard.TargetName='MouseOverHighlight' Storyboard.TargetProperty='(Shape.Fill).(SolidColorBrush.Color)'>
  12.               <SplineColorKeyFrame KeyTime='00:00:00' Value='#FFFFDF00' />
  13.             </ColorAnimationUsingKeyFrames>
  14.             <DoubleAnimationUsingKeyFrames BeginTime='00:00:00' Duration='00:00:00.0010000' Storyboard.TargetName='MouseOverHighlight' Storyboard.TargetProperty='(UIElement.Opacity)'>
  15.               <SplineDoubleKeyFrame KeyTime='00:00:00' Value='0.24' />
  16.             </DoubleAnimationUsingKeyFrames>
  17.           </Storyboard>
  18.         </vsm:VisualState>
  19.       </vsm:VisualStateGroup>
  20.       <vsm:VisualStateGroup x:Name='SelectionStates'>
  21.         <vsm:VisualStateGroup.Transitions>
  22.           <vsm:VisualTransition GeneratedDuration='0:0:0.1' />
  23.         </vsm:VisualStateGroup.Transitions>
  24.         <vsm:VisualState x:Name='Unselected' />
  25.         <vsm:VisualState x:Name='Selected'>
  26.           <Storyboard>
  27.             <DoubleAnimationUsingKeyFrames BeginTime='00:00:00' Duration='00:00:00.0010000' Storyboard.TargetName='SelectionHighlight' Storyboard.TargetProperty='(UIElement.Opacity)'>
  28.               <SplineDoubleKeyFrame KeyTime='00:00:00' Value='0.18' />
  29.             </DoubleAnimationUsingKeyFrames>
  30.           </Storyboard>
  31.         </vsm:VisualState>
  32.       </vsm:VisualStateGroup>
  33.       <vsm:VisualStateGroup x:Name='RevealStates'>
  34.         <vsm:VisualState x:Name='Shown' />
  35.         <vsm:VisualState x:Name='Hidden' />
  36.       </vsm:VisualStateGroup>
  37.     </vsm:VisualStateManager.VisualStateGroups>
  38.     <ToolTipService.ToolTip>
  39.       <ContentControl Content='{TemplateBinding FormattedDependentValue}' />
  40.     </ToolTipService.ToolTip>
  41.     <Ellipse Fill='{TemplateBinding Background}' Stroke='{TemplateBinding BorderBrush}' />
  42.     <Ellipse RenderTransformOrigin='0.661,0.321'>
  43.       <Ellipse.Fill>
  44.         <RadialGradientBrush GradientOrigin='0.681,0.308'>
  45.           <GradientStop Color='#00FFFFFF' />
  46.           <GradientStop Color='#FF3D3A3A' Offset='1' />
  47.         </RadialGradientBrush>
  48.       </Ellipse.Fill>
  49.     </Ellipse>
  50.     <Ellipse Fill='Red' Opacity='0' x:Name='SelectionHighlight' />
  51.     <Ellipse Fill='White' Opacity='0' x:Name='MouseOverHighlight' />
  52.   </Grid>
  53. </ControlTemplate>

Notice that I set the opacity of the "Root" grid to 1 (it is 0 in the original style) and removed all storyboards from the "Shown" and "Hidden" VisualStates. So now we have a ControlTemplate that shows the datapoint right away (opaycity to 1) and does not need any additional CPU cycles for animations (no storyboards).

In order to be able to attach these animation-less templates to the respective data series we need an additional template:

XML:
  1. <Style TargetType='charting:LineDataPoint' x:Key='LineDataPointStyleBlue'>
  2.   <Setter Property='Background'>
  3.     <Setter.Value>
  4.       <RadialGradientBrush>
  5.         <RadialGradientBrush.RelativeTransform>
  6.           <TransformGroup>
  7.             <ScaleTransform CenterX='0.5' CenterY='0.5' ScaleX='2.09' ScaleY='1.819' />
  8.             <TranslateTransform X='-0.425' Y='-0.486' />
  9.           </TransformGroup>
  10.         </RadialGradientBrush.RelativeTransform>
  11.         <GradientStop Color='#FFB9D6F7' />
  12.         <GradientStop Color='#FF284B70' Offset='1' />
  13.       </RadialGradientBrush>
  14.     </Setter.Value>
  15.   </Setter>
  16.   <Setter Property='BorderBrush' Value='Gray' />
  17.   <Setter Property='BorderThickness' Value='1' />
  18.   <Setter Property='IsTabStop' Value='False' />
  19.   <Setter Property='Width' Value='8' />
  20.   <Setter Property='Height' Value='8' />
  21.   <Setter Property='Template' Value='{StaticResource LineNoTransition}' />
  22. </Style>

Notice that I went to the source of the chart library and copied the original style for "Background" getting rid of the hideous "orange". Plus notice the Value for the Template that points to our new animation-less template.

Last but not least attach the new dataline template to the chart:

XML:
  1. <charting:Chart x:Name="Performance">
  2.    <charting:LineSeries
  3.       x:Name="SleepTimez"
  4.       ItemsSource="{Binding Path=Performance.SleepTimez}"
  5.       Title="T"
  6.       DependentValuePath="Count"
  7.       IndependentValuePath="Time"
  8.       DataPointStyle="{StaticResource LineDataPointStyleBlue}" />
  9.    <charting:LineSeries
  10.       x:Name="ListSleepTimez"
  11.       ItemsSource="{Binding Path=Performance.ListSleepTimez}"
  12.       Title="LT"
  13.       DependentValuePath="Count"
  14.       IndependentValuePath="Time"
  15.       DataPointStyle="{StaticResource LineDataPointStyleRed}" />
  16.    <charting:LineSeries
  17.       x:Name="ChartSleepTimez"
  18.       ItemsSource="{Binding Path=Performance.ChartSleepTimez}"
  19.       Title="CT"
  20.       DependentValuePath="Count"
  21.       IndependentValuePath="Time"
  22.       DataPointStyle="{StaticResource LineDataPointStyleLightGreen}" />
  23. </charting:Chart>

And that's pretty much it. Unfortunatelly I was not able to make the style palette work again - so right now I have to manually choose and attach colors to the various data series. But that's good enough for me right now.

I have not figured out yet how to remove the "hide" transition. It seems as if the removal of datapoints from a graph still trigger an animation, but I don't know why. Any hints?

Download: Complete LineDataPoint style

Post to Twitter Tweet this

June 27th, 2009 12:13 am | Comments (0)

Falling into the deep hole of Constructor Autodiscovery

by Tobias Hertkorn on June 24th, 2009

I am using Unity right now do some IoC. All I wanted to do is get an instance of the WCF Client that was auto-generated for me. So naively I thought this would be enough:

C#:
  1. m_container.RegisterType<IService, ServiceClient>();

But that greeted me with a kinda weird error message:

Microsoft.Practices.ObjectBuilder2.BuildFailedException: The current build operation (build key Build Key[Test.ServiceReference.ServiceClient, null]) failed: The current build operation (build key Build Key[Test.ServiceReference.ServiceClient, null]) failed: The type ServiceClient has multiple constructors of length 2. Unable to disambiguate. (Strategy type DynamicMethodConstructorStrategy, index 0) (Strategy type BuildPlanStrategy, index 3) ---> Microsoft.Practices.ObjectBuilder2.BuildFailedException: The current build operation (build key Build Key[Test.ServiceReference.ServiceClient, null]) failed: The type ServiceClient has multiple constructors of length 2. Unable to disambiguate. (Strategy type DynamicMethodConstructorStrategy, index 0) ---> System.InvalidOperationException: The type ServiceClient has multiple constructors of length 2. Unable to disambiguate.
bei Microsoft.Practices.ObjectBuilder2.ConstructorSelectorPolicyBase`1.FindLongestConstructor(Type typeToConstruct)
bei Microsoft.Practices.ObjectBuilder2.ConstructorSelectorPolicyBase`1.SelectConstructor(IBuilderContext context)
bei Microsoft.Practices.ObjectBuilder2.DynamicMethodConstructorStrategy.PreBuildUp(IBuilderContext context)
bei Microsoft.Practices.ObjectBuilder2.StrategyChain.ExecuteBuildUp(IBuilderContext context)
--- Ende der internen Ausnahmestapelüberwachung ---
bei Microsoft.Practices.ObjectBuilder2.StrategyChain.ExecuteBuildUp(IBuilderContext context)
bei Microsoft.Practices.ObjectBuilder2.DynamicMethodBuildPlanCreatorPolicy.CreatePlan(IBuilderContext context, Object buildKey)
bei Microsoft.Practices.ObjectBuilder2.BuildPlanStrategy.PreBuildUp(IBuilderContext context)
bei Microsoft.Practices.ObjectBuilder2.StrategyChain.ExecuteBuildUp(IBuilderContext context)
--- Ende der internen Ausnahmestapelüberwachung ---
bei Microsoft.Practices.ObjectBuilder2.StrategyChain.ExecuteBuildUp(IBuilderContext context)
bei Microsoft.Practices.Unity.ObjectBuilder.NamedTypeDependencyResolverPolicy.Resolve(IBuilderContext context)
bei BuildUp_Test.ServiceReference.ServiceClient(IBuilderContext )

Turns out: I am used to Windsor Castle... Apparently Unity thinks of itself high enough to decide what it can and can't construct. Meaning - instead of using the constructor it could satisfy with all the types I registered (in other words the default constructor since I did not register anything else) it went straight for the longest constructor it could find - and got rightfully confused since there are multiple in any service client of length two.

Well, after a bit of soul searching I came up with this solution: "Specify the type of constructor I want Unity to use"

C#:
  1. m_container.RegisterType<IService, ServiceClient>()
  2.                 .Configure<InjectedMembers>()
  3.                 .ConfigureInjectionFor<ServiceClient>(new InjectionConstructor());

Now the default constructor is used when resolving IService to ServiceClient. (Note that the constructor of InjectionConstructor has no parameters...)

Still think that the Constructor discovery process of Unity is straight brain-dead. But now it works...

Post to Twitter Tweet this

June 24th, 2009 6:14 pm | Comments (3)
Tobi + C# = T# - Blogged blogoscoop