Software Mechanics
Why do we even have that lever?

Unity and Silverlight: It can be done!

April 9, 2008 10:33 by Chris

Today was our weekly "slack time" day, where I get to go sit in a conference room and experiment with new technology. Today I did this:



Yep, got Unity running under Silverlight 2.0 beta 1. In the end it took me less than four hours (at least 30 minutes of which was waiting for the SDK to install and the obligatory xaml designer crashes). I made a couple boneheaded mistakes  in the project files, so I'm not going to post sources just yet.

Here's an overview of the porting process:

  • Install 2.0 Beta 1 plugin, SDK, Unit test tools and project templates.
  • Create a new Silverlight project.
  • Create Silverlight libraries for ObjectBuilder and Unity.
  • Copy the source for full OB, Unity, into the new projects. Add the files to the project.
  • Compile, fix errors, compile, fix errors, ... etc. ;-)

 Here's the issues I ran into.

Standard binary serialization is gone. As a result, the SerializationInfo and StreamingContext classes are not available. This is an issue because FxCop insists on the four standard constructors on every custom exception class. In Silverlight, there are now THREE standard constructors, not four. So remove them from all the custom exception classes.

The existing code uses methods like Array.Find and List<T>.RemoveAll. Many of these methods were removed from the Silverlight version. So I replaced them with the equivalent Linq expressions. This actually made some code a lot easier to read, which is nice.

System.Configuration and everything associated with it doesn't exist, which involved removing a bunch of stuff from the unit tests. My fault really, they should have been in a separate fixture to begin with.

The IL generation stuff is actually supported on Silverlight, which pleasantly surpised me. I did have to make one change though. When generating the build plan, we have some code that checks to see if you're in full trust, and chooses where to host the dynamic method based on the trust level. This way, in full trust we can do injection on internal or private classes. In Silverlight, you can't do this, and you can't choose where to host your dynamic methods anyway. The net result is that set of code goes away, and we just accept that you can't inject non-public stuff in Silverlight. Unfortunately, that meant changing a bunch of stuff in the test code, as lots of the tests have private nested classes as test subjects. Had to go through and change them all to public, and it worked.

One really weird thing I ran into is in the StagedStrategyChain class. This class takes an Enum, and uses it to determine how many stages the chain has. To figure out how many stages are present, we called Enum.GetValues(), which returns all the enum constant names. Guess what? This method is gone in Silverlight. I cheated by just looping up from zero to find the highest value defined by the enum; it's grotesque, but it worked.

One thing I'd like to throw in: I really, really appreciate the creation of the Silverlight unit test fixture. It would have taken a LOT longer to figure out if this thing was working without it. And since the SL runner is source compatible with the MSTest stuff, I just copied my existing tests in and they just ran. Very, very cool! 

I'm not going to be posting this code just yet, for a couple of reasons. The first is that the project isn't good enough yet; I really need to reorganize the solution I have right now, for example. The second reason is that this is NOT a supported scenario, and I don't want to give the impression it is. So you'll never see this on the Unity codeplex site, for example. Maybe it could be put on UnityContrib eventually?

Anyway, just wanted to let folks know it's not only possible, it was actually pretty easy!


Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5
Tags:
Categories: p&p | Silverlight | Unity
Actions: E-mail | Permalink | Comments (17) | Comment RSSRSS comment feed

Unity 1.0 is released!

April 4, 2008 09:43 by Chris

I just finished uploading the release of Unity 1.0 to Codeplex. The bits have also been uploaded to MSDN, but it'll take a while to propagate.

The release includes the Unity MSI, plus two more MSIs with Visual Studio 2005 and 2008 integrated documentation. Rather than bloat the main download with three copies of the docs, we chose to make the separate installers available for those who want them.

We've also split out the source as a separate download, so for those who don't trust MSIs or something, you can still grab the source code.

Enjoy! I'm off to work on version 1.1. :-)

 


Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5
Tags:
Categories: .NET | p&p | Unity
Actions: E-mail | Permalink | Comments (2) | Comment RSSRSS comment feed

Using Unity and the ASP.NET MVC Preview 2

March 13, 2008 07:40 by Chris

The recent release of the ASP.NET MVC Framework made a change to the IControllerFactory interface at the request of users of dependency injection containers. Instead of passing the controller factory the type of controller desired, it now gets the string from the route, and the factory can now resolve that type however it wishes.

This fits with most other DI containers, since they have to have everything pre-configured anyway. However, Unity is a little different, in that you don't have to register concrete types ahead of time. This change requires Unity users to register types ahead of time like everyone else, or do reflection to find controller types at runtime. Kind of annoying.

However, there's another answer. Recent (ahem) discussions on the net has shown an obsession with interfaces, to the point that even when there's a useful base class that will solve the problem, many will go straight to the interface and duplicate a lot of work.

In this case, there's a simple way to hook Unity up to ASP.NET MVC preview 2. Rather than implement IControllerFactory, inherit from DefaultControllerFactory instead. There's a method in there, GetControllerInstance, which is called after the name has already been resolved to a type. In other words, the DefaultControllerFactory already does the reflection for you.

Here's the code:

    public class UnityControllerFactory : DefaultControllerFactory
    {
        IUnityContainer container;

        public UnityControllerFactory(IUnityContainer container)
        {
            this.container = container;
        }

        protected override IController GetControllerInstance(Type controllerType)
        {
            if (controllerType == null)
            {
                throw new ArgumentNullException("controllerType");
            }
            if (!typeof(IController).IsAssignableFrom(controllerType))
            {
                throw new ArgumentException("Type requested is not a controller", "controllerType");
            }

            return container.Resolve(controllerType) as IController;
 }

To hook this up, in global.asax.cs, do something like this:

            IUnityContainer container = new UnityContainer();

            // Configure container here

            IControllerFactory controllerFactory = new UnityControllerFactory(container);
            ControllerBuilder.Current.SetControllerFactory(controllerFactory);

Simple and easy! Hope this helps!

 


Currently rated 3.2 by 6 people

  • Currently 3.166667/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5
Tags: ,
Categories: .NET | Unity
Actions: E-mail | Permalink | Comments (7) | Comment RSSRSS comment feed

Reconstructing ObjectBuilder - Changes to the IBuilderStrategy interface

March 9, 2008 17:50 by Chris

Reconstructing ObjectBuilder

Ok, so I'm not so imaginitive with titles.

I'd going to be posting snippets of Unity internals here, and in particular getting into the sometimes ugly details of ObjectBuilder and how we use it, and how we've changed it.

To start off, I'd like to share probably the biggest change to the original OB API. For those who read my previous series, you'll remember the definition of IBuilderStrategy looked like this:

1  public interface IBuilderStrategy
2  {
3    object BuildUp(IBuilderContext context, object buildKey, object existing);
4
5    object TearDown(IBuilderContext context, object item);
7  }

To implement a strategy, you implemented this interface. When you were done, you returned the value you were building up. To invoke the rest of the strategy change, you wrote:

base.BuildUp(context, buildKey, existing);

This call would invoke the rest of the strategy chain and return the result back to you. Many strategies simply returned this value after having done their work.

This approach has the advantage of simplicity, but in practice is a real pain. The major issue is debugging and profiling. If you've ever seen a stack trace from when ObjectBuilder goes wrong, you'll know what I'm talking about. You can easily get 35 or 40 stack frames of nothing but BuilderStrategy.BuildUp, and it becomes next to impossible to figure out where the chain went wrong.

I got motivated to do something about this when we were doing some profiling on the Web Client Software Factory library, which uses OB1. Our perf guy told us "your problem is in ObjectBuilder." I asked him how he knew that, and he showed me his profile, which had nothing but OB calls in it, in gigantic stacks 70 or 80 layers deep. It is actually turning out that OB is not the determining factor, but we could see that becuase of all the noise.

So, as a result, the IBuilderStrategy interface now looks like this:

1  public interface IBuilderStrategy
2  {
3       void PreBuildUp(IBuilderContext context);
4
5       void PostBuildUp(IBuilderContext context);
6
7       void PreTearDown(IBuilderContext context);
8
9       void PostTearDown(IBuilderContext context);
10 }

I've explicitly split the processing of a strategy into two parts, Pre and Post. This is similar to the way WCF behaviors are designed. All the Pre- methods of the strategies are called going forward down the strategy chain, then the Post- methods are called in the reverse order.

Notice that the existing and buildKey parameters are now gone. These values are now included in the IBuilderContext, and strategies can change them as the strategy chain executes.

Now, the pre and post methods do not need to explicitly invoke the rest of the chain. Instead, the StrategyChain class now has ExecuteBuildUp and ExecuteTearDown methods that call the strategies in the appropriate order. Also, if you write a strategy that needs to short-circuit the chain and return early, there's a BuildComplete flag in the context that, if set true by a strategy, will stop the chain from continuing.

The net result of this chain is that stacks are a LOT shallower; you will only get as deep as the number of recursive dependencies. We also got a single spot to wrap and handle exceptions, which was a nice benefit. It turns out to be slightly faster as well, but perf wasn't a real priority behind this change.

There are a couple of lost capabilities, unfortunately. You can't completely change the context, recursively invoke the rest of the chain, and then switch back to the original context and execute the rest of the chain again. This was a sufficiently rare scenario (none of the built-in OB strategies used this technique) that I don't feel bad about losing it.

If you've used classic OB and are wondering what's going on with the strategies, I hope this helps.


Currently rated 4.5 by 2 people

  • Currently 4.5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5
Tags:
Categories: Unity
Actions: E-mail | Permalink | Comments (0) | Comment RSSRSS comment feed

End of the Deconstruction

February 28, 2008 18:01 by Chris

I'd like to thank everyone for the great reception for my Deconstructing ObjectBuilder series. It's good to know I was filling a gap.

However, I'm currently thinking that I'm not going to post the last segment on using OB to wire up to the event broker. I was editing the text for the post last night, and I realized that it needed serious work to update to OB2. Serious enough to take at least a couple of days. And, quite honestly, I think I've got more important things to write about.

So I think I'm going to call an end to the Deconstructing ObjectBuilder series. And intead start a new one, on Unity, extensibility, and how Unity uses OB2. The EventBroker example I've been using is actually included as one of the Unity quickstarts, so I don't even need to update that code for the container. Wink

I have uploaded all the code from the DeconstructingObjectBuilder series so far. This code even works, unlike some of the blog posts with last minute typos in it. Feel free to play with it. You'll need to download and compile the OB2 sources first. But to be honest, with Unity out there (which has made some significant changes to OB2) I'm not sure how much effort that's worth right now. You can tell me.

Thanks for reading, now on to something (sorta) new!

DeconstructingObjectBuilder.zip (37.93 kb)


Be the first to rate this post

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