Damon Payne: Hand waving Silverlight Architect

103db signal to noise ratio at < .03% total harmonic distortion
Solution Architect, software developer, geek
Damon Payne at Blogged
2009 Microsoft MVP - Client App Dev
2007 Microsoft MVP - Solution Architecture
 Sunday, September 14, 2008

If you are just joining, you might want to start from the beginning: http://www.damonpayne.com/2008/09/14/RunTimeIsDesignTimeForAGT0.aspx

Layouts and Modules

I’m about to steal some ideas that are in common use, ideas from PRISM, Castle Windsor, the Visual Studio design-time environment, and a thousand other things.  I’ll briefly explain some of the core concepts here.

Modules or Services

In a well designed Windows Forms application, one would have a proper separation of concerns.  Suppose my form was for place orders for big purple couches.  I would have a CouchOrderForm that implements ICouchOrderView with very little logic: populating values or potential values only, perhaps with Data Binding, and event handlers.  These event handlers would delegate the actual work to a CouchOrderPresenter of some kind.  CouchOrderPresenter would probably use to a CouchOrderDataAccess class or perhaps a CouchBussinessProcess class to accomplish the necessary tasks, and update the UI using a combination of data binding and events.  I know people who would frown upon this as “primitive”, but even getting this far would be miles ahead of the average .NET project I saw as a consultant.

For testability, this design accomplishes a fair bit of concern-separating.  I can test almost my entire program without messing around with “how do I test the logic that’s in the Form?”  For example, I have often created a unit test class that implements the ICouchOrderView interface and does asserts in the various callback.  This means that a database and whatever other “real” components are required must be present and that might be very Heavy for unit test time.  If my code was written to use ICouchDataAccess instead of CouchOrderDataAccess, it’s suddenly much easier to mock out parts of my framework.  I might also be able to supply different ICouchDataAccess implementations at run time if that makes sense for my program – though I think this need is often horribly misunderstood and over used by many advocates. 

When I originally encountered this idea we called it the Service Locator Pattern in Java.  The term “service” is a loaded word.  I used to ask interview questions along the lines of “What is a Class? Now what is an object?  Now what is a Component?  Now what is a Service?”  I would change terminology here to say “module” or “strategy”, but Service is the commonly known semantic of our times, so I’ll use service to talk about program chunks that are essentially managed components.  My Component Container/Service Locator will be a ServiceManager.  It might be useful to have some common behaviors for these components, so IService will be the base interface for components.

When I add these things to the IoC project, I notice that when I choose to Add à new item, “Interface” is not an option for Silverlight projects.  Doesn’t MSFT want us to take Silverlight seriously?

The idea is that the ServiceManager will figure out what classes are available when a component asks for an IFoo implementation.  I’ve seen lots of fascinating ways of doing this in Full Framework projects.  Config files, loading every assembly in a certain directory, manually resolving at program startup, and others.  In Silverlight, the AppManifest.xml file contains a “Deployment.Parts” tag, which contains all the assemblies that get deployed with your app.  Still, I don’t seem to be able to call Assembly.Load() on these, so for now I’m going to go with manual resolution at program startup.

Generics make getting started on a service locator a breeze:

    public class ServiceManager

    {

        static ServiceManager()

        {

            _services = new Dictionary<Type, object>();

        }

 

        private static Dictionary<Type, object> _services;

 

        /// <summary>

        /// Pass in a list of strong types and determine what service interfaces they provide to us:

        /// </summary>

        /// <param name="types"></param>

        public static void Manage(List<Type> types)

        {

            Type baseServiceType = typeof(IService);

 

            foreach (Type t in types)

            {

                Type[] interfaces = t.GetInterfaces();

                foreach (Type iface in interfaces)

                {

                    if(iface != baseServiceType)

                    {

                        Type svcInterface = iface.GetInterface("DamonPayne.AGT.IoC.IService", false);

                        if (null != svcInterface)//We know this interface extends IService

                        {

                            _services.Add(iface, ObtainDefaultInstance(t));

                        }

                    }

                }

            }

        }

 

        /// <summary>

        /// Since an object could implement more than one interface, we may have in in here under multiple keys

        /// </summary>

        /// <param name="t"></param>

        /// <returns></returns>

        protected static object ObtainDefaultInstance(Type t)

        {

            object o = null;

            var q = from val in _services.Values.AsQueryable<object>()

                    where val.GetType().IsAssignableFrom(t)

                    select val;

 

            o = q.FirstOrDefault<object>();

            if (null == o)

            {

                Type[] noArg = new Type[0];

                o = t.GetConstructor(noArg).Invoke(null);

            }

 

            return o;

        }

 

        public static TServiceType Resolve<TServiceType>()

        {

            TServiceType svc = default(TServiceType);

            Type t = typeof(TServiceType);

            if (_services.ContainsKey(t))

            {

                svc = (TServiceType)_services[t];

            }

            else

            {

                throw new NotSupportedException(string.Format("A provider for {0} was not found", t));

            }

            return svc;

        }

 

 

    }

Now I need something to use to test this out.  I think I might want a Logging service of some kind to display messages to me, so I’ll create an ILogService interface in the IoC project:

    public interface ILogService: IService

    {

        void Debug(string message);

    }

 

And I’ll need to provide an implementation somewhere.  For now I’ll add a folder/namespace to the Layout project and create a simple do-nothing implementation.  In the Application_Startup event handler I can now start setting things up.  I create a MemoryLogger and:

        private void Application_Startup(object sender, StartupEventArgs e)

        {

            this.RootVisual = new Page();

            List<Type> s = new List<Type>

            {

                typeof(MemoryLogger)

            };

            ServiceManager.Manage(s);

 

            ILogService logger = ServiceManager.Resolve<ILogService>();

            //success!

        }

Now I’m starting to get somewhere.  I’m planning on creating an implicit way to get these services later.  There seems to be two schools of thought here: setting services on serviced components using a property or field, and supplying all the necessary services in the constructor.  For my next step, though, I want to get some things on the screen to help visualize how this is going to fit together.

Composite UI

My notion of a Region Manager is stolen directly from “Composite Application Guidance for WPF”.  We can abstract out the idea of a Window and various views and evolve the idea of how the UI should function over time.  I know that I will have the notion of a View, which is docked into a Region, which is managed by a RegionManager of some kind.  First, we think about these interactions and come up with a first try at interfaces.  Just to start getting some things on the screen, a View will be just this:

    public interface IView

    {

        /// <summary>

        /// Grid, etc. extends canvas

        /// </summary>

        Canvas LayoutRoot { get; }

    }

I’m not sure that I need an explicit implementation of a Region, so my IRegionManager consists of the following:

    public interface IRegionManager : IService

    {

  UIElement RootVisual { get; }

        List<string> RegionNames { get; }

        void AddView(IView v);

        void AddView(IView v, string regionName);

        IView GetView(string regionName);

        List<IView> Views { get; }

    }

The IRegionManager implementation does what I need it to do for now.  Clearly, our Page is a suitable class for serving as the Region Manager.  In the last article I envisioned three regions, but now that I’ve got my logging idea I’ll extend it to four.  I need a region for a Toolbox, Designer Surface, Property Grid, and Message Console.  Implementing the IRegionManager interface and supplying some default content to be sure I’m laying things out the way I want, the XAML and runtime application looks like so:

<UserControl x:Class="DamonPayne.HTLayout.Page"

    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

    Width="800" Height="600">

    <Canvas x:Name="LayoutRoot" Background="White">

        <Grid x:Name="_regionArea" Background="Red" Width="800" Height="600">

            <Grid.RowDefinitions>

                <RowDefinition></RowDefinition>

                <RowDefinition></RowDefinition>

            </Grid.RowDefinitions>

            <Grid.ColumnDefinitions>

                <ColumnDefinition></ColumnDefinition>

                <ColumnDefinition></ColumnDefinition>

                <ColumnDefinition></ColumnDefinition>

            </Grid.ColumnDefinitions>

            <Canvas x:Name="Toolbox" Grid.Row="0" Grid.Column="0" Width="Auto">               

                <TextBlock>I am toolbox</TextBlock>

            </Canvas>

            <Canvas x:Name="DesignSurface" Grid.Row="0" Grid.Column="1" Width="Auto">

                <TextBlock>I am design surface</TextBlock>

            </Canvas>

            <Canvas x:Name="PropertyGrid" Grid.Row="0" Grid.Column="2" Width="Auto">

                <TextBlock>I am property grid</TextBlock>

            </Canvas>

            <Canvas x:Name="MessageConsole" Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="3">

                <TextBlock>I am the message console</TextBlock>

            </Canvas>

        </Grid>

    </Canvas>

The IRegionManager implementation is incredibly straightforward and in the source code at the end of this article.  Applying some refactoring we get the ServiceManager to create the Page for us and the application startup now looks like this:

        private void Application_Startup(object sender, StartupEventArgs e)

        {           

            List<Type> s = new List<Type>

            {

                typeof(MemoryLogger),

                typeof(Page)

            };

            ServiceManager.Manage(s);

 

            IRegionManager mgr = ServiceManager.Resolve<IRegionManager>();

            RootVisual = mgr.RootVisual;

            //success!

        }

The next thing to decide is how IViews get loaded into our IRegionManager on startup.  It would be nice if I could use the same mechanism for IService wire-up, but this article is getting a bit long already.   For now, I’m going to create the visual design for the message console to set up the next article.  I create a Controls folder/namespace to hold my application specific UI components and put a MessageConsoleView in.  This component will be a UserControl that implements IView.  As soon as I implemented IView, however, I see that LayoutRoot was a poor choice of name since it forced an explicit interface implementation, so I refactor to IView.VisualRoot instead.  I also see that when I said “Canvas” was a good root because Canvas and Grid derived, I meant “UserControl”, so I refactor that too.

Now I have something to think about for the next article.  The MessageConsoleView will obviously need to get at my ILogService implementation…

Licensing

Now that I’ve got some code in here, I should decide on how I’m going to share that.  The Creative Commons license seems to fit my goals.  I’m not super up to date on open source license wording, but this one will do for now, in code-snippet form:

<?xml version="1.0" encoding="utf-8"?>

<CodeSnippets

    xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">

  <CodeSnippet Format="1.0.0">

    <Header>

      <Title>

        Creative Commons License

      </Title>

    </Header>

    <Snippet>

      <Code Language="CSharp">

        <![CDATA[

/*

Creative Commons - attribution-noncommerical-share alike 3.0 Unported

          You are free to copy, distribute, and transmit this work.

          You are free to adapt the work.

        Under the following conditions:

          -You must attribute the author(Damon Payne, http://www.damonpayne.com) for this work but not in a way

          that suggests the author endorses you or your use of the work.

          -You may not use this work for commercial purposes

          -If you alter, transform, or build upon this work, you are free to distribute the work under the same or similar license to this one.

*/

        ]]>

      </Code>

    </Snippet>

  </CodeSnippet>

</CodeSnippets>

If anyone out there wants to provide input on this license, please do.

Source code throug this article: DamonPayne.AGT[1].zip (538.15 KB)



Sunday, September 14, 2008 3:12:17 PM (Central Standard Time, UTC-06:00)  #    Disclaimer  |  Comments [0]  |  Trackback

Often times, the act of explaining a question out loud to another person involves a lot of complex and fleeting thought, we think at over 600 words per minute, and coalescing into sentences for the transmission from mental constructs to speech.  The thought process involved in this preparation for vocalization often restructures the problem in such a way that the question is answered in the asking.  An early mentor of mine called this effect “Talking to the bear”; he had a teddy bear on top of his monitor who served as a sounding board for his toughest issues, and later my issues as well. 

For a while, I’ve wanted to do some Reality Blogging.  Take a complex idea and a set of design goals, state them out loud, and slowly work towards a completed product or module.  Often times, I have presented an idea in, say, eight parts, because the idea was large enough to warrant breaking up for explanation.  The idea was fully baked before the first part was published.  The notion here, rather, is not to complete the idea but rather to work with both Visual Studio and Word open; to state design goals and see how they pan out later, to see how easy it was to refactor, to see a complex idea emerge out of nothing.

The Goal

The goal is to have an extensible, lightweight design surface and design-time environment for Silverlight.  As I have written about in the past (http://www.damonpayne.com/2007/04/24/Designer0.aspx) there are any number of neat reasons for which it would be useful to have  design time capabilities at runtime in applications.  My example application will be a Home Theater Layout application for Silverlight.  The vision is something like this:

So, I want this to be able to work in a manner we are familiar with: I drag things out of a toolbox onto a design surface, where I am allowed to drag and resize things.  When I select things I will be able to edit the selected item using a property grid.  I’ll want to support limited undo and be able to select multiple things to move around and so forth.

 In Windows forms, you can host the designer in your own application though it’s a lot of work. When the time came to make tradeoffs, the WPF designer “Cider” was not made hostable outside of Visual Studio.  Besides, there is no PropertyGrid for Silverlight, and no <<lots of other stuff>> for Silverlight, so this is really a big effort. 

Silver is Argentum in Latin, ergo its period table symbol is AG.  Ergo is also Latin, how fun.  Anyway, all the cool kids abbreviate Silverlight as “AG” and nothing sensible like “SL”.  The Latin word for “design” is more or less tela.  I dub thee, The ArGentum Tela project, or AGT for short. 

Design Goals

As Anders Heijlsberg said way back when he was famous for something called Delphi, it’s good to start out with some goals, it’s good to think about “how do I want people to use this?”  I have some design goals and functional requirements:

·         I want different aspects of the UI to function independent of each other

·         I want to be able to swap out different implementations for any aspects of the program that makes sense for

·         I want component to component communication to happen without components having references to each other

·         I want the building blocks of my program to feel like Serviced Components

·         I want to be able to serialize the results of my designer surface for later retrieval

·         I want a healthy # of common tasks accessible through the keyboard

·         I want this to work on the Mac.  I thought everyone was running Windows by now but apparently there are literally dozens of Mac users out there, so I should take their poor incomplete keyboards into account.

·         I want to package this as a reusable design-time library with a Reference Implementation – the home theater layout tool

·         I want to have as little code-behind/presenter as possible

I’ve been re-reading my GoF book, arguing with Dan almost every day, and reviewing the way the PRISM code looks.  I have some ideas about how I want to accomplish all of this.  As of now, my solution looks like this then:

·         DamonPayne.AGT

o   DamonPayne.HTLayout – the Silverlight sample project

o   HTLayoutWeb – a web test project for HTLayout

o   DamonPayne.AGT.IoC – how’s that for a name?  I’m going to pursue some inversion of control concepts for Silverlight, and that stuff will live in this assembly.

o   DamonPayne.AGT.Design – the code that makes the designer work will live here.

 

What’s next?

I’ve got Word open and Visual Studio open; it’s time to get started.  Where to begin?  In the next article we’ll start exploring some basic concepts for layouts and components.  Want to play along?  I’ll post the current source code at the end of each step.

 DamonPayne.AGT[0].zip (515.64 KB)



Sunday, September 14, 2008 10:24:11 AM (Central Standard Time, UTC-06:00)  #    Disclaimer  |  Comments [2]  |  Trackback
 Thursday, September 11, 2008

In VS2008 SP1, some of the project property pages include some minor changes.  For web sites and WCF projects, there is a "Servers" area under the Web tab.  You can, for these settings, store them in the Project file rather than the user-level settings.  I view this as a good thing.

The decision as to what settings are project level and what settings are user level have always made me scratch my head, I cannot determine any reasonable hueristic as to how the choice is made.  Should users be able to choose their own warning level?  Probably.  Should users be able to choose to optimize code or not?  Probably.  Should "allow unsafe code" be something that a user can toggle?  Probably not.  If my project contains unsafe and I build without that setting it will clearly not compile, what good is that?  Perhaps Team Server addresses some of these issues, but I for one would like to see more settings optionally tied to the project.



Thursday, September 11, 2008 11:35:41 AM (Central Standard Time, UTC-06:00)  #    Disclaimer  |  Comments [0]  |  Trackback
 Tuesday, September 09, 2008

http://rss.slashdot.org/~r/Slashdot/slashdot/~3/bPjNCxSc91M/article.pl

 

Read that, let it soak in, smile.  I have blogged about this before but I can't help giggling to myself.  I assume all the people who screamed for Microsoft to be fined, broken up, shackled with special restrictions (they have to run a lot of their plans by the DOJ), and forced to give up intellectual property such as Active Directory protocols to their competitors (IP that cost billions to develop) will now be screaming for the same thing to happen to Google.  Oh, and Apple is not far behind.  Apple has a great hit on their hands with iTunes, but they are being given an ultimatum in the EU to lower prices or face a full antitrust investigation. 

 

In case you're not following the irony, let me spell it out for you: Business B tries to compete with Business A in a free marketplace and ultimately is not as successful as they'd like to be.  Four main categories of options remain to Business B.  They can give up.  They can keep trying.  They can resort to illegal measures like kidnapping, blackmailing, and extortion.  But why resort to illegal measures when the legal measures are just as forceful, just as damaging, but perfectly above the board.  If Business A is big enough and Business B can find enough malcontents to help with legal funds, they can lobby the government to open an Antitrust suit.  No one states this better than Mr. Zuck in his DotNetRocks interview concerning the politics surrounding the OOXML debacle.  I urge you to give it a listen here: http://www.dotnetrocks.com/default.aspx?showNum=335

 

As Jonathan puts it, there are only three ways you can get yourself into Anitrust trouble in the US and the EU. As luck would have it, you must merely follow all three of these rules at once and you are safe:

  1. Do not charge the same price as your competitors. This is Collusion and harms consumers.
  2. Do not charge less than your competitors.  This is Dumping and harms consumers.
  3. Do not charge more than your competitors.  This is Monopoly Rent and harms consumers.

Why would antitrust law involve a set of rules that are mutually excluisve and impossible to follow?  If you feel the intent of Uncle Sam is to "protect consumers" this is impossible to reconcile except perhaps by assuming the law is broken and not meeting its intent.  The law is not broken, and is precisely filling its intent. Without these laws, the bureaucrats would have a hard time marketing their sales as Thugs for Hire, but I'll come back to that.

 

Assuming a business wished to avoid Monopoly status at all costs, how might they go about this?  Are there objective measurements they can follow to avoid obtaining a certain market share?  Are there maximum profit margins they must seek to remain below?  There are, in many states, minimum margins certain businesses must observe.  A contractor in Wisconsin who marks up materials less than 6% will find themselves in court.  I suppose this is to protect consumers from the mental anguish resulting in determining how to spend that extra money?  Imagine that perfectly objective metrics existed for determining at what point Monopoly status is gained.  The business in question has only poor choices.  The business can opt to wait for the other shoe to fall, knowing that at any time their shareholders' wealth will be drained into legal defense.  The business can engage in self destructive behavior hoping to lose market share; if the business is a C-corp the agents are legally forbidden to do this and will find themselves in court.  Fingally, the business can start lobbying!  How might a Monopoly notification from our government look, anyway?

Congratulations, you're a monopoly!

The United States government congratulates you on your achievements.  Please be aware that starting today, you are forbidden to run your business in the same fashion that got you here.   Enclosed, please find campaign donation envelopes for the major political parties.

 

 

Google and Yahoo should not be investigated; Apple should not be investigated; Microsoft should not have been investigated.  There are already comprehensive fraud laws at the State and Federal level to protect consumers.  Beyond this, a business can only come to market dominance through a series of voluntary exchanges with clients and partners.  It is only the government, and not businesses, that can establish artificial barriers to competition.  Business owners have a right to their property.  Government power brokers will seize any excuse to violate or threaten to violate that right in order to furthur their own agendas.  Google, Apple, and Yahoo! are finding out that if you cannot pay the government Protection Money through the lobbyists, those that did open up their pockets will soon have access to all your hard work - either as it becomes public record entered into evidence at trial or forcibly taken from you by a binding judgement.  Just remember that by your willingness to infringe on the rights of others, you opened the door for the desecration of your own rights. 

 

I don't expect to hear public outrage against Google and Yahoo! ; only unpopular businesses receive this treatment.

 

Following the original Microsoft antitrust trials,  Bill Gates is famously quoted as saying "I should have spent more time in Washington".  This is to say, he feels he should have spent more time participating in lobbying and favor purchasing and less time running his business.  The power brokers in Washington wouldn't have it any other way.



Tuesday, September 09, 2008 2:07:15 PM (Central Standard Time, UTC-06:00)  #    Disclaimer  |  Comments [0]  |  Trackback
 Friday, August 01, 2008

I was listening to the most recent Thirsty Developer, http://thirstydeveloper.com/2008/07/26/TheThirstyDeveloper28SCRUMAndAgileInTheEnterprise.aspx.  Sean is a great guy and I'm glad Larry and Dave were able to connect with him.  One thing I found interesting is that they mention using Scrum for things other than software development projects.  It is indeed a generic principle based on empirical process management.  Scrum is a simple idea, like most powerful ideas.  At CarSpot, we are (more or less) using Scrum for our inter-departmental communication as well as software development.  The various managers meet with their teams in a brief, daily standup, and at 2:00pm we have a Scrum of Scrums where department managers/directors talk about what's going on and are able to air any complaints about the service they're getting from other departments.  We are using ScrumWorks at this time, but I'm thinking we can create something that suits our needs better.

In addition, my family operates on Scrum.  You may have noticed that I'm fairly fond of my toys.  A lot of married men that I talk to claim they would never be "allowed" to have such things.  They use terms like "SWMBO", She Who Must Be Obeyed.  Really?  Honestly, you guys are either:

  1. Spineless.
  2. Broke.
  3. Pretending to be spineless by saying its your wife and not your better judgement keeping you from blowing tons of money on things you really know you shouldn't have.  You think by displacing this acetism to your spouse you appear more manly to your peers.  In fact you appear to be spineless and your friends feel sorry for you, thinking you must not be happy in your relationship.
  4. You don't really value your own happiness.

In my family, we have a Family Backlog.  Just like in Scrum, everything goes on there, no matter what.  Nothing is a "no", just a low priority.  I don't think my Tesla Roadster will be on a Sprint any time soon.  Still, it's a great way to communicate and feel things out.  No one feels slighted because there is a known order of what we're working on, and we can have ridiculous things as long as we respect the fact that we take turns and do what makes sense.  My wife will be getting her own diving gear and curtains in the whole house following my recent speaker purchases.  Nothing is listed as being for "us", unless its really for US.  I don't know how many times a friend or coworker has complained that they can't get a new TV because the bedroom set was for "them".  These men could care less about a new bedroom set, they want an HDTV dammit.  This system works for us, everyone is happy, and the backlog can be reprioritized as our needs and wishes change.  Besides being a fair system, I'm lucky enough to be married to a great woman who really cares about my happiness and - get this - doesn't think she knows better than me what will make me happy.  So men, put your new Corvette on your family backlog and be aware you may wind up funding a total kitchen makeover directly before or after it.  If families really want to be fair with limited resources, to really do the things that are important to the family and to each individual therein, you could do a lot worse than Scrum.



Friday, August 01, 2008 12:41:24 PM (Central Standard Time, UTC-06:00)  #    Disclaimer  |  Comments [0]  |  Trackback
 Monday, July 28, 2008

As some people know, I'm very into 2channel audio listening and home theater.  I'm also a bit of a Klipsch fanboy.  I'm also intersted in acoustic science and this has all led to a listening room that is considered by some to be a bit over the top.  Recently, I've built four Silverlight applications related to my Audio/Home Theater hobbies.  I'm going to briefly introduce them here, and get into code in future articles.

Group Photo

Every year, Klipsch has an event that has come to be known simply as The Pilgrimage.  This boils down to a trip by hardcore Klipsch nuts to one of two sacred locations: the original home of Klipsch and present day manufacturing center in Hope, AR, or the engineering labs in Indianapolis, IN.  In the 1930's and 40's folks at RCA, Bell Labs, James B Lansing and Paul W. Klipsch were inventing what we call Hi-Fi.  There's a lot of fascinating history at these events, a chance to see new stuff under NDA, play with engineering equipment, and so forth.  Every year a group photo is taken.  This time, I thought creating a Silverlight application with "hotspots" would be the best way to annotate the photo: tie people's first names and forum names to a face. 

The picture scales to the size of your browser, so with a big monitor you can start to see some of the detail in the high-res original photo.  Mousing over people displays as much name as they wanted to give, forum name, and where they're from.  If you participate in any Internet community that has a real-world component, something like this to tie someone's internet handle to "Oh yeah I had some beers with him..." is pretty neat.

The application is live at http://www.klipschcorner.com/silverlight/2008/PilgrimageFaces/

Listening Room Carousel

My Klipsch site, KlipschCorner.com, has a feature where crazy people like myself can share photos of their listening rooms.  I have previously posted my conversion of the "carousel" example to a nicer Silverlight 2 appliction, and I just updated it for Beta 2, the code will be coming of course.

The application is live at http://www.klipschcorner.com/HTCarousel.aspx?Id=1&Title=Damon's Palladium Paradise

Room Mode Calculator

Many people don’t know that the shape and size of your room can have a much larger affect on sound than what equipment is in the listening room.  Everyone probably learned in high school science class that when waves collide, constructive or destructive interference can be created.  When those waves are sound waves bouncing around your walls what you end up with is not hearing what’s actually in the recording.  In order to model this behavior before building a room (or to help make educated guesses on an existing room), a room mode calculator is called for.  This tells us what frequencies stack up and what the distribution of modes is:

The application is live at

http://www.klipschcorner.com/Tools/ModeCalc.aspx

Palladium Deep Zoom

Let’s say you were really into Klipsch speakers.  Let’s further say that Klipsch came out with a product that was considered by early reviewers to be among the best speakers in the world.  Would you let the fact that they cost $20k stop you from purchasing them?  You probably would!; but then you would not be me.  You would take tons of photos to meticulously document the un-boxing and setup process so that audio fans everywhere could live vicariously through you, and so that is what I’ve done.

The application uses the standard mouse wheel/click zooming about as well has showing a blurb about each photo as you click on it ala the Hard Rock site.

The center channel zoom app is live at

http://www.klipschcorner.com/PalladiumZoom.aspx and the floorstanding speakers at http://www.klipschcorner.com/PalladiumZoom.aspx?model=p39f

As soon as I get caught up on some other things, I’ll dive into creating some articles that get into the useful parts of the XAML, C#, or Blend2.5 tricks it took to create these applications.  For now, I hope some people will appreciate these awesome speakers!



Monday, July 28, 2008 11:03:14 AM (Central Standard Time, UTC-06:00)  #    Disclaimer  |  Comments [0]  |  Trackback

Well, just over a year ago, I was drooling over the Klipsch Palladium speakers that had been announced.  Look who found their way into my home theater this weekend:

You can check out other photos and sizes at http://www.klipschcorner.com/SystemProfileDisplay.aspx?Id=1

The photos don't do them justice, they are extremely attractive.  They are extremely expensive, I'm thinking this will be the last pair of main speakers I ever buy.



Monday, July 28, 2008 9:18:51 AM (Central Standard Time, UTC-06:00)  #    Disclaimer  |  Comments [0]  |  Trackback
 Monday, July 21, 2008

Adam Kinney has post some articles in the past showing a Silverlight application for displaying gamer cards.  When the Playstation 3 finally caught up and created a "Portable ID", I thought this would be a decent chance to demonstrate some Silverlight chops. Yes, I have a PS3 and not an XBox360.  I thought maybe I'd make an application with unnecessary animations and sounds for fun, perhaps allow you to sort friends and setup notifcations that are not available from the PSN.  Here's my Playstation portable ID:

The gist of the online status is simply a JPG, in my case http://pid.us.playstation.com/user/drpayne.jpg , that gets updated when your status changes via the console.  Excited to run off and write code I created a Silverlight 2 app and set about downloading this JPG.  Except that it doesn't work because of Silverlight's cross domain security policies.  I'm not a genious in TCP/IP or DNS/BIND, but the policies used by Silverlight (mimicing those used by Flash) seem overly restrictive and make some scenarios that should be common and easy difficult or un-doable.  There may be a reverse-tunnel situation or similar DNS trickery that is capable with this type of application, but denial of service?  Check out what I just did in this blog posting:

<img border=0 src="http://pid.us.playstation.com/user/drpayne.jpg"/

When the markup for this page is downloaded to your browser, the browser then issues seperate http requests for content that lives on other servers.  That content comes from us.playstation.com, and Google analytics, and Blogged, and others.  This is, seemingly, not a security or denial of service risk in this particular situation.  The PS3 network site shown above did not need to place a client policy XML file in the server root, and in fact they would need to do work to prevent cross domain access of this type.  Sure, Silverlight has more than just HTTP networking capabilities, in fact for a future article I have a full blown instant messanger application implemented in Silverlight using Sockets.  In terms of being a good Technology Citizen, I can see Microsoft wanting to be very careful concerning what it allows devlopers to do with more general socket programming.  But HTTP?  Isn't this part of what the web is "about" ?

What do you think?  Is the cross domain policy employed by Silverlight too restrictive?  Does it not go far enough?  Just right?



Monday, July 21, 2008 12:20:51 PM (Central Standard Time, UTC-06:00)  #    Disclaimer  |  Comments [0]  |  Trackback
 Tuesday, July 08, 2008

I made reference a few times last year to some big things being in the works but that it was hush hush.

Our company, called CarSpot.com since 1995, was acquired by AutoTrader.com, the biggest player in the online automotive space with an overwhelming market share.  CarSpot was picked up for our innovative online, mobile, and desktop solutions to pervasive data aquisition, aggregation, and distribution problems.  To AutoTrader, having a small satellite office that is much more agile than a multi-billion dollar entity was an attractive proposition.  Let's face it, some large companies couldn't change the font of a paragraph burried in an obscure section of their website without a 50 person team of project managers, business analysts, marketing, managers, designers, and developers.  Here at CarSpot, though, an impressive amount of functionality was written and supported by basically four technical people.

CarSpot traditionally was very casual.  Developers have always been trusted to get their work done, a simple practice that's practically unheard of out there.  People came and went as they pleased, a lot of beer was purchased on the company credit cards.  There was no internet monitoring, we played a game of Quake III at work sometimes, almost any link you might get from a friend marked "NSFW" was really just fine at CarSpot.  We had power and freedom and we did some good work; we were encouraged to goof off on things that might turn into good things for the company.  What we didn't have was tons of money to buy all the servers we should have had for redundancy and there were sometimes some tools it obviously made sense to have that we just couldn't buy.  I had been consulting with CarSpot for years, but when I joined full time in August of 2006 I was the only spouse/kids/mortgage employee in the shop; benefits weren't all that family friendly.

In the post-purchase world, the former owner is still the President of this division.  We have all the upside of a large company like HR, benefits, money, and infrastructure, and AutoTrader is making sure we keep our culture.  We are considered the "R&D Division" and are expected to keep AutoTrader.com ahead of the technology adoption curve.  With a mix of more traditional projects and products with lists of enhancements for sales and "mess with this to see what works and what could be better" type mandates this is shaping up to be an ideal place for geeks to work.  Hopefully the two employees I've added to my group this year are enjoying themselves. 

For the longest time, we were forbidden from publicly mentioning this pending an "Official corporate communication strategy".  This never happened, so its high time I made a public announcement to the geek community.



Tuesday, July 08, 2008 11:39:16 AM (Central Standard Time, UTC-06:00)  #    Disclaimer  |  Comments [4]  |  Trackback
 Monday, July 07, 2008

After debating for at least 6 months I pulled the trigger on a new dSLR which showed up today.  The Canon Rebel XTi, 10 megapixel; it ships with a 18-55mm f/3.5-5.6 lens.

I take absolutely terrible photos with any camera, and this camera is (among other things) a means to learning how to do it right.  I've been meaning to take more pictures of the kids and various other things and this will be a big help.  Plus, it's cool.  I ran around taking pics of everyone and  everything at Carspot today.  Watch my flickr stream in the coming days.



Monday, July 07, 2008 2:45:50 PM (Central Standard Time, UTC-06:00)  #    Disclaimer  |  Comments [0]  |  Trackback

Pardon me while I scratch my head and try to decipher this paradox:

 

This is one seriously confused program.



Monday, July 07, 2008 9:53:14 AM (Central Standard Time, UTC-06:00)  #    Disclaimer  |  Comments [1]  |  Trackback