Friday, February 22, 2008

Scott Guthrie talks about silverlight 2.0 and it is looking to be exactly what I hoped it would be. It seems they are really aiming for enabling RIA applications, but cross platform, cross browser.

The big announcement is the inclusion of built-in controls. It was a big disappointment to me that they were not included in silverlight 1.0 or 1.1, but they are included now!

My take on this is that it will revolutionize the way we build software. As you might know, I've been involved in creating a big RIA application with xbap. Although it was great, we did not have a very good story on the use of the 'browser'. I was reminded time and time again that it was weird to use the browser, while it was not cross platform or even cross browser. We had good reasons to go for xbap none the less, but I'm looking forward to seeing what we can do with Silverlight 2.0.

Friday, February 22, 2008 9:28:46 PM (Romance Standard Time, UTC+01:00)  #    Comments [0]  |  Trackback

I sometimes do it, but don't like to do it too often. But this one, I just want to archive here so I can always find it: Beatriz has just released a great ready-to-use drag and drop library. She has also written a terrific blog post about it here, that shows the steps she took to achieve it.

I just ran the project and it performs well, has insertion adorners and even allows dragging and dropping within the same list. Good stuff!

Friday, February 22, 2008 1:54:19 PM (Romance Standard Time, UTC+01:00)  #    Comments [0]  |  Trackback

This is the fourth of a series about using Workflow Foundation to control your UI Logic in a WPF application. The full table of contents:

  • Workflow as controller: Introducing <M,V,C> where M: ViewModel, V : WPF, C : WF
  • Part II, starting the application, and the adapter
  • Intermezzo: new sample application
  • Part III, your first view
  • Part IV, decoupling view from controller
  • Part V, marshalling commands from WPF to WF
  • Part VI, Injecting a controller in a subview / workspace
  • Part VII, IOC on the cheap: injecting and retrieving objects
  • Part VIII, Broadcasting for all to see
    Recap

    In the first post, the complete solution was presented. I am presenting a solution to use workflow as the controller part in your MVC inspired WPF application. It is inspired on the thought that you do not need complex frameworks, because WPF already gives you great power (routed eventing, resources). So, no IOC is used, no event aggregator etcetera: it's taken care of by WPF and WF, a natural fit.
    The solution is very decoupled and I feel it's a great advantage to be able to visual your control logic.
    In the previous post, I talked about the various ways to show a view, and actually already talked about the decoupling mechanism: commands.

  • I'm very lucky to have received some good comments from Wekemf about tight coupling. I urge you to read those comments and maybe chime in.

    In this post I will not return on that subject, but will quickly address two important activities that help in configuring your system quickly: the SetMainContent activity and the SetDataContext activity and sending WPF commands to WF's HandleCommand.

    SetMainContent activity

    A controller adapter is a normal WPF contentcontrol. It has the job to participate in the visual tree on behalf of our workflow controller class. To actually attach a view to it, we need to set it's content property.

    As shown in the previous post, you can just set on in xaml yourself, but it's more logical to let the workflow decide on the view. Ofcourse, the best approach is totally up to you.

    I usually use the stateinitalization activity to set up a view for us. I drag in the SetMainContent activity, and choose a type from the references assemblies.
    If it weren't for this step, the controller assembly would not need a reference to the view assembly at all. I found it very cool to be able to select a type with the typebrowser and just have it show up.

    The typebrowser is located in an assembly I have put in the externalAssemblies folder. It is a project, not started by me. The code did not work when I got my hands on it, but I managed to fix it by using a hammer. Check out this post to learn more about this great design-time experience!

    If you have a business need to decouple even further, you would need to adjust the SetMainContent activity, and instead of sending a real Type, send a string key or whatever. Then you would create some mapping functionality to map that key to the actual view.

    When the adapter get's notified by the SetMainContentMessage that it needs to set a content, it will just create the view (using reflection) and place it as it's own content.

    SetDataContext activity

    I do not like MVP at all, where the presenter talks back to the view directly (using an interface or something). I feel it's way too 'pushy' and way too much work. I believe in databinding (especially WPF bindings, I think Microsoft got it right this time). You view should just bind to your domain objects. In many cases, it's better to create a wrapper for the domainobjects, so you have the opportunity to supply some shortcut properties or view specific stuff: you might have a list of products, and you want the view to display the sum of the prices. That is a great opportunity for the viewmodel to expose a 'Sum' property that the view can simply bind to.

    The object that is used as a ViewModel should live with the controller who will be able to communicate with it.
    I usually create an internal public class, simply called ViewModel and have the controller inject that class with domain objects.

    The Set DataContext activity is very similar to the SetMainContent activity, in that it let's the adapter know it has to set a datacontext on itself.
    You configure the SetDataContext activity simply by choosing a field or property of your controller.

    In small sample applications, I have used the 'invoking' event, to hook up some code that actually initializes the ViewModel object.

    Sending WPF commands to the Workflow: HandleCommandActivity

    The HandleCommandActivity is really what makes using the solution so easy. I have blogged about it already extensively, and I will just summarize here:

    Workflow has a difficult communication story. You need to define your incoming and outgoing calls in an ExternalDataExchangeService. Then you have to hook up events in your workflow to listen to incoming calls/events. It is not possible to listen to the same events in two different states, without using the very difficult CorrelationTechnique.

    This is not necessary for our usage. I have created the HandleCommand activity to just listen to a queue with a specific name. That name is defined by the command we are listening to. So, if you want your workflow to react when you send it the string 'workflowRules', you would just drag in the HandleCommand and configure the Command property to read 'workflowRules'. No need to setup a special event for it.

    The commandService class has a PostCommand method, that you can call to put a message on the queue. That's all there is to it.

    So, when we receive a WPF command, we cast it to a RoutedUI command. The commandname is used to form a SimpleCommandMessage which can be used as input to the PostCommand method.

      1         #region command sinks
      2         private void CmdExecuted(object sender, ExecutedRoutedEventArgs e)
      3         {
      4             string commandname = (e.Command as RoutedUICommand).Name;
      5
      6             PostCommand(commandname, e.Parameter);
      7
      8         }
      9
    10         private void PostCommand(string commandname, object Parameter)
    11         {
    12             if (implementedCommands.Contains(commandname))
    13             {
    14                 commandSvc.PostCommand(new SimpleCommandMessage(instance.InstanceId, commandname, Parameter));
    15             }
    16         }
    17
    18         private void CmdCanExecute(object sender, CanExecuteRoutedEventArgs e)
    19         {
    20             string commandName = (e.Command as RoutedUICommand).Name;
    21
    22             if (implementedCommands.Contains(commandName))
    23             {
    24                 e.CanExecute = commandSvc.CanExecute(new SimpleCommandMessage(instance.InstanceId, commandName));
    25             }
    26         }
    27
    28         #endregion

    As you can see, I first check if the workflow even implements such a command. If not, it would be too expensive to send it to the workflow.
    Also, check out the CmdCanExecute method. It actually makes it possible for the workflow to put rules on the HandleCommand activity that are used to figure out if a command can be executed. For instance, if you are not authorized to do something, the command was never in CanExecute, so the button that hooks up to it was always dimmed!

    I hope that clears up some questions. Let me know what you think!

    Friday, February 22, 2008 11:24:20 AM (Romance Standard Time, UTC+01:00)  #    Comments [0]  |  Trackback

    This is the fifth of a series about how to go about using postcompilation in your solutions. You can read it as a tutorial on how to use PostSharp. I am very much new to that framework, but the power it provides could seriously change how you build your applications. While working on the EF contrib project, I had to dive into PostSharp, and I hope to share some of the things I learned along the way.

    This post introduces the weaver, that will do exciting stuff for us.

    The full table of contents:

  • Introducing Entity Framework Contrib- Easy IPoco implementation V 0.1
  • Part II, Postsharp Core versus Postsharp Laos
  • Part III, the compound aspect
  • Part IV, the PocoInterfaceSubaspect (composition aspect)
  • Part V, hooking up the weaver
  • Part VI, the EdmScalarWeaver
    Recap

    We wish to create an attribute that can be placed on top of our ordinary Poco class, that will magically transform it into a class that implements the 3 IPoco interfaces. These are needed by the Entity Framework to do it's work. We will use PostSharp to do this.
    Our previous post talked about the compound attribute and how it goes about implementing interfaces on classes for you.

    This post will look at how we are going to hook up a weaver to do more complex stuff, not directly supported by the provided Laos aspects.

    But first I want to clear up a statement I made here: 'I found it wildly confusing the first time I came across the two parts of postsharp. Laos is such a high-level abstraction, that you use it quite differently from Core. In the latter, you have to spinup your own weaver, in Laos you do not ever see a weaver. '
    It is not true that you do not ever see a weaver when using Laos. I should have been more clear: Laos offers a great deal of functionality that you can use without going into a weaver.

    We want to put custom attributes on our type that EF needs (the EDM scalar attributes on top of properties and the EDM type attribute that connects your type to a EDM type). Laos does not seem to have a ready-to-use aspect that provides that functionality, so we are going to need to hook into the weaver ourselves! How exciting!
    Thankfully, we can derive from TypeLevelAspectWeaver to make life easy enough.

    Hooking up a weaver

    The cool thing about using the weaver is, that you can put it in it's own assembly and not have to reference it in the assemblies that you are postcompiling. That is quite important, because the weaver depends on PostSharp.Core and there is another license attached to it.
    The PocoAttribute adds an aspect to the collection, like it did for the other aspects:

      1 public override void ProvideAspects(object element, LaosReflectionAspectCollection collection)
      2         {
      3             // Get the target type.
      4             Type targetType = (Type)element;
      5
      6 ....
    10             // inspect the complete class and add EDM scalar attributes to the properties
    11             collection.AddAspect(targetType, new EDMAttributesSubAspect(this.EDMContainerName, Name, NamespaceName, PathToConfigFile));
    .....
    12 }

    At line 11, the EDMAttributesSubAspect is added. This means that when Laos is ready to start working, it will check that aspect to see what it should do. Let's look at it now:

        [Serializable]
        internal class EDMAttributesSubAspect : ILaosTypeLevelAspect
        {
            #region fields and properties
            internal string EDMContainerName { get; set; }

            internal string TypeName { get; set; }
            internal string NamespaceName { get; set; }
            internal string PathToConfigFile { get; set; }
            #endregion

            #region ctor
            /// <summary>
            /// ctor
            /// </summary>
            /// <param name="EDMContainerName">the container name</param>
            /// <param name="NamespaceName">namespacename, can be null</param>
            /// <param name="TypeName">typename, can be null</param>
            public EDMAttributesSubAspect(string EDMContainerName, string TypeName, string NamespaceName, string PathToConfigFile)
            {
                this.EDMContainerName = EDMContainerName;
                this.TypeName = TypeName;
                this.NamespaceName = NamespaceName;
                this.PathToConfigFile = PathToConfigFile;
            } 
            #endregion

            #region ILaosTypeLevelAspect Members

            public void CompileTimeInitialize(Type type)
            {
            }

            public bool CompileTimeValidate(Type type)
            {
                return true;
            }

            public void RuntimeInitialize(Type type)
            {
            }

            #endregion

            #region ILaosWeavableAspect Members

            public int AspectPriority
            {
                get { return int.MinValue; }
            }

            #endregion 

        }

    You might be surprised to hear that this is the complete aspect!! Nothing that hints at what is to come.

    When such a thing happens, you might be stumped. But obviously you will immediately think to check the assemblyinfo file of the PostSharp4EF assembly:

    [assembly: PostSharp.Extensibility.ReferencingAssembliesRequirePostSharp("PocoTypeWeaver", "EntityFrameworkContrib.PostSharp4EF.Weaver")]
    [assembly: InternalsVisibleTo("EntityFrameworkContrib.PostSharp4EF.Weaver")]

    Okay, I was kidding. You wouldn't have thought of that. ;-)

    The first statement there, instructs PostSharp to look for a plugin, with name PocoTypeWeaver to process all assemblies that are referencing this assembly. It is just another way of expressing requirements. I could have put that inside the attribute. But I did not.

    The plugin file can be found in the weaver assembly. It is just a normal text file with naming convention that matches the entire assembly name + "psplugin". The contents of that file:

    <?xml version="1.0" encoding="utf-8" ?>
    <PlugIn xmlns="http://schemas.postsharp.org/1.0/configuration">
      <TaskType Name="PocoTypeWeaver" 
                Implementation="EntityFrameworkContrib.PostSharp4EF.Weaver.PocoEDMAttributesWeaverFactory, EntityFrameworkContrib.PostSharp4EF.Weaver">
      </TaskType>
    </PlugIn>

    Here you will see a task PocoTypeWeaver and a reference to an implementation of a weaver factory. So, our PocoAttribute needs the pocoTypeWeaver and it can get one through the use of a factory. But, since your client assembly will not have a reference to this weaver assembly (which contains this mapping file), we need some way to tell it where to look. Enter the psproj file that was put inside your client assembly:

    <Project xmlns="http://schemas.postsharp.org/1.0/configuration">
    	<SearchPath Directory="../EntityFrameworkContrib.PostSharp4EF.Weaver/bin/{$Configuration}"/>
    	<SearchPath Directory="{$SearchPath}" />
    	<Tasks>
    		<AutoDetect />
    		<Compile TargetFile="{$Output}" IntermediateDirectory="{$IntermediateDirectory}"  CleanIntermediate="false" />
    	</Tasks>
    </Project>

    This psproj file is used by postsharp to extend it's searchpath. This means that on machines that are building the solution, you will need to supply some path where PostSharp can find the just mentioned psplugin file.

    Please note: there are other ways to configure the searchpath and possibly better ways to setup a system like this. There is a default searchpath and you could also put your plugin file there.

    The weaver factory
        public class PocoEDMAttributesWeaverFactory : Task, ILaosAspectWeaverFactory
        {

            #region ILaosAspectWeaverFactory Members
            /// <summary>
            /// creates the weaver
            /// </summary>
            /// <param name="aspect">the EDMAttributesSubAspect that instantiated this factory</param>
            /// <returns>the weaver that will do the lowlever hardcore work</returns>
            public LaosAspectWeaver CreateAspectWeaver(PostSharp.Laos.ILaosAspect aspect)
            {
                if (aspect is EDMAttributesSubAspect)
                {
                    EDMAttributesSubAspect edmAttributesAspect = (EDMAttributesSubAspect)aspect;
                    return new PocoEDMAttributesWeaver(edmAttributesAspect.EDMContainerName);
                }

                return null;
            }

            #endregion
        }

    Nothing special there. Using a factory allows you to supply different weavers for different aspects.

    So, to recap: we attached a plugin that did not do much itself. We used the assemblyinfo to tell PostSharp it should always use a certain task when compiling assemblies that are referencing our attribute assembly. We used the psproj file to make PostSharp search in the right spot and we used a psplugin file to tell map the task name to an actual factory.
    The factory creates our weaver, and we will discuss that in the next post!

  • Friday, February 22, 2008 10:41:17 AM (Romance Standard Time, UTC+01:00)  #    Comments [0]  |  Trackback
     Thursday, February 21, 2008

    I got a mail yesterday from a German student asking about the future of workflow and my thoughts on it. I will share the thread. It was written in a hurry, so take it for what it is. Leave a comment to give him another view point.

    Read from bottom to top.

    -----

    my reply:

    What you are describing does indeed sound like a typical WF application, and it is absolutely suitable for that.

    Custom activities: don't be afraid. Just create one that is a wrapper around your huge ole-api. Creating an activity is little more than deriving from Activity and overriding the execute method.
    Put some properties on there and of you go.
    Or create multiple activities that do different things to the ole object.

    It sounds to me that you want to re-host the workflow designer. That is certainly do-able and there is a project from some1 you can download that actually did that. However, it was in need of more debugging. I don't have the url here. Sorry.

    What WF is not, is a magical system that requires no development. It is really meant to be a foundation, which a developer uses and builds upon to create a system that really suits the client wishes. So that means, configuring it, creating external data exchange services and building custom activities. Only then will you create a system that your client can use in the way you described. You need to mold it to behave like you want.

    In our case, it was definitely the developers that created the workflows. Best we could hope for was that business analysts could understand it (and they did). However, I've always felt it was possible to create a system that they could use directly.

    Success!
    Ruurd

    -----Original Message-----
    From: Sven
    Sent: woensdag 20 februari 2008 20:56
    To: me
    Subject: Re: Some questions about the future of WF

    Hi Ruurd,

    thank you very much for your in-depth statement! I had not expected this detailed level ;-)

    Actually as a part of my project I have to evaluate if WWF fits into an existing CRM Application.
    It should be possible for solution partners (customizing the application for their customers) without in-depth programming knowledge for example to "wire together" some custom activites to visually build for example the processing of an incoming mail, a little workflow for some little approval process (like you press a button inside the application on an address form, the workflow gets some field from the current record, decides based on the field which e-mail model to use, sends the email and finally writes some information to the same record, like "e-mail XY sent") or things like that... (sounds like a classic
    Flow-WF)
    But their could be use for some "state machines", too. Like there is a WF-Service running and dispatching incoming mails to different employees...

    Is WWF suitable for this ? These things could be done today in the application by coding some huge VB-Scripts, there is a huge OLE-API in the application...

    What I missed is a "CustomOLEActivity" to call whatever function in an application with OLE-API (there are a lot on the market) and to simply return some values...
    (the ExternalDataExchange/CommunicationActivity with wca.exe-Tool-way looks like beeing very complicated - at least if you have to build a CustomActivity for a huge OLE-API, or have I missed something out ?)

    On my "first look" the designer looked a bit complicated (even for people with some advanced knowledge, i have to target not the computer dummies, but also not the programmers on the other hand, some level "between", lets say "System Administrators"), but perhaps you can give me from your own experiance some hints in which direction I have to go for this...
    (who is editing the workflows in your big project?)

    Implementing everything "from scratch" looks like an even bigger effort... (would be the other choice...)

    Thanks a lot for your help and guidance !

    Bye
    Sven

    my reply:
    >
    > Basically, I see quite a few problems surrounding WF. It is very
    > shielded, the designer is not very good still and there is no good
    > update strategy (updating long running persisted workflows to new
    > versions). I think that last issue is one of the biggest problems it
    > has, although it hasn't gotten much publicity.
    >
    > However, as a platform, it does what it should do very well. They are
    > going to use it as the biztalk workflow engine and are already using
    > it as the human workflow engine for sharepoint.
    >
    > I feel we are moving toward an industry that needs to mature (the IT
    > development industry I mean). It is looking for DSL's and other ways
    > to make developing software a more manageable and predictable process.
    > Workflow has a definite place in that eco-system, where you can
    > visualize the flow of your program. This means you have an artifact
    > that will actually help a developer communicate with a business analyst or a client.
    >
    > To be concrete:
    >
    > So, why do I think developers have been slow to take it up: a
    > difficult programming model and some serious issues that are not well understood yet.
    > It is a radically different approach to building software, and it
    > takes time for ppl to feel confident with it.
    >
    > Is there a future: I say _yes_. If you understand the problems of
    > todays WF framework, you can already build great things, and I've
    > heard about some of the stuff that Microsoft is doing on the next
    > version, which will alleviate some big problems. Since we need this
    > kind of technology to build better software, there is definitely a future for it.
    >
    > Is it already used in the industry: Well, I have used it, but I have
    > yet to hear of big projects using it. Then again, Biztalk is used
    > extensively and the WF engine is every bit as powerful. (rules engine maybe slightly less).
    > Sorry, no example possible...)
    >
    > I do not think it will disappear.
    >
    > Kind Regards,
    > Ruurd Boeke
    >
    > -----Original Message-----
    > From: Sven
    > Sent: woensdag 20 februari 2008 19:48
    > To: me
    > Subject: Some questions about the future of WF
    >
    > Hello!
    >
    > I'm a computer student from the university of applied sciences of
    > Emden, Germany.
    >
    > Actually I'm working on a project dealing with the Windows Workflow
    > Foundation.
    >
    > As it was introduced one and a half years ago, but I see not so much
    > implementations or books about it, I wonder why it has been adopted so
    > slowly by the developpers.
    >
    > What do you think about this? (just some thought will be helpful for
    > me!) Is there a "future" ? Or will this stay an "Microsoft Internal" - Affair ?
    >
    > Is this already used in the industry ? Where ?
    > (If you could give me some examples from your experience this would be
    > very helpful for my work)
    >
    > Is this really a technology to build on or might it disappear slowly
    > like other "cool" stuff in the past ?
    >
    > Thank you very much in advance for any hint!
    >
    > Sincerely,
    > Sven

    Thursday, February 21, 2008 5:38:13 PM (Romance Standard Time, UTC+01:00)  #    Comments [0]  |  Trackback

    Just a short message to let everyone know I have built the first version of default value support for efcontrib.

    I will follow up with a bigger post on the limitations. For now, only ints and strings will be processed.

    Thursday, February 21, 2008 4:44:26 PM (Romance Standard Time, UTC+01:00)  #    Comments [0]  |  Trackback

    This is the fourth of a series about how to go about using postcompilation in your solutions. You can read it as a tutorial on how to use PostSharp. I am very much new to that framework, but the power it provides could seriously change how you build your applications. While working on the EF contrib project, I had to dive into PostSharp, and I hope to share some of the things I learned along the way.

    This post introduces the first real step I took: the compound aspect.

    The full table of contents:

  • Introducing Entity Framework Contrib- Easy IPoco implementation V 0.1
  • Part II, Postsharp Core versus Postsharp Laos
  • Part III, the compound aspect
  • Part IV, the PocoInterfaceSubaspect (composition aspect)
  • Part V, hooking up the weaver
  • Part VI, the EdmScalarWeaver
  • Recap

    We wish to create an attribute that can be placed on top of our ordinary Poco class, that will magically transform it into a class that implements the 3 IPoco interfaces. These are needed by the Entity Framework to do it's work. We will use PostSharp to do this.
    Our previous post talked about the composite attribute and how it allows you to combine multiple actions into one attribute. That's easier to use for the endusers.

    This post we will look into the PocoInterfaceSubAspect and how it does it's job.

    The Composition aspect

    You can remember placing the PocoInterfaceSubAspect on the element like so:

                // implement the three IPOCO interfaces on the class
                collection.AddAspect(targetType, new PocoInterfacesSubAspect());

    Postsharp will instantiate our aspect during it's weaving. Our aspect inherits from CompositionAspect. Let's take a step back and discuss what the CompositionAspect does.

    The compositionAspect is an extremely powerful aspect which allows you to implement an interface onto another object. So let's say you want to make an object be an iList at runtime, without dealing with it in your source: use composition to implement iList!

    We are implementing the three iPoco interfaces. Because the CompositionAspect wants one type to composite (and I did not feel like doing it three times) I created a facade interface:

        public interface IPocoFacade : IEntityWithChangeTracker, IEntityWithKey, IEntityWithRelationships
        {
        }

    Now, how does the weaver go about using this aspect to actually implement the code needed? It will ask for the public interface to inject and then also ask for an implementation object. The implementation object is the one that gets to do the dirty work. PostSharp will basically inject that implementation object into your object and then create all your interface code to just use that implementation object.

    The PocoInterfacesSubAspect

    The complete aspect looks like this:

        [Serializable]
        sealed class PocoInterfacesSubAspect : CompositionAspect
        {

            public override object CreateImplementationObject(InstanceBoundLaosEventArgs eventArgs)
            {
                return new PocoImplementation(eventArgs.Instance);
            }

            public override Type GetPublicInterface(Type containerType)
            {
                return typeof(IPocoFacade);
            }

            /// <summary>
            /// Gets weaving options.
            /// </summary>
            /// <returns>Weaving options specifying that the implementation accessor interface (<see cref="IComposed{T}"/>)
            /// should be exposed, and that the implementation of interfaces should be silently ignored if they are
            /// already implemented in the parent types.</returns>
            public override CompositionAspectOptions GetOptions()
            {
                return
                    CompositionAspectOptions.GenerateImplementationAccessor |
                    CompositionAspectOptions.IgnoreIfAlreadyImplemented;
            }
        }

     

    Clearly, we are more interested in the implementation object.

    The implementation

    Part of the implemenation object looks like this:

       class PocoImplementation : IPocoFacade
        {
            private readonly object instance;

            public PocoImplementation(object instance)
            {
                this.instance = instance;
            }
    }

    You can see it implements the IPocoFacade interface. It expects our businessobject that was decorated with the Poco attribute in it's constructor.

    We now just look at the code the Ado.Net team has given us to see how to implement these interfaces.

    The IEntityWithKey for instance, is quite easy:

            #region key
            EntityKey _entityKey = null;

            // Define the EntityKey property for the class.
            EntityKey IEntityWithKey.EntityKey
            {
                get
                {
                    return _entityKey;
                }
                set
                {
                    // Set the EntityKey property, if it is not set.
                    // Report the change if the change tracker exists.
                    if (_changeTracker != null)
                    {
                        _changeTracker.EntityMemberChanging("-EntityKey-");
                        _entityKey = value;
                        _changeTracker.EntityMemberChanged("-EntityKey-");
                    }
                    else
                    {
                        _entityKey = value;
                    }
                }
            }
            #endregion

    Done.

    Since I first want to know if there is interest, I have not implemented relationships and complex types yet.

    Thursday, February 21, 2008 12:25:32 PM (Romance Standard Time, UTC+01:00)  #    Comments [2]  |  Trackback

    This is the third of a series about using Workflow Foundation to control your UI Logic in a WPF application. The full table of contents:

  • Workflow as controller: Introducing <M,V,C> where M: ViewModel, V : WPF, C : WF
  • Part II, starting the application, and the adapter
  • Intermezzo: new sample application
  • Part III, your first view
  • Part IV, decoupling view from controller
  • Part V, marshalling commands from WPF to WF
  • Part VI, Injecting a controller in a subview / workspace
  • Part VII, IOC on the cheap: injecting and retrieving objects
  • Part VIII, Broadcasting for all to see
  • Recap

    In the first post, the complete solution was presented. I am presenting a solution to use workflow as the controller part in your MVC inspired WPF application. It is inspired on the thought that you do not need complex frameworks, because WPF already gives you great power (routed eventing, resources). So, no IOC is used, no event aggregator etcetera: it's taken care of by WPF and WF, a natural fit.
    The solution is very decoupled and I feel it's a great advantage to be able to visual your control logic.
    In the previous post, I showed a wizard style application.

    This post follows Part II, starting the application and the adapter. In that post we started our shell and explained how the adapter communicates with a workflow instance, how it can react to commands (normal RoutedUI events from wpf controls) and react to events by the command service.

    We will now continue, by looking at a simple view.

    View responsibility

    Let's first look at how we perceive a view in the MVC paradigm.
    A view should be nothing more than the visualization of your data. The only authority it has, is the authority to decide how to represent a piece of data on the screen. That means it should not contain any business logic. Be very strict about this: the responsibility of a view is the visualization of data.

    So, let's take a look at a common scenario where these lines may blur.
    Take a list of products and let's say that if we have a new product-line that has been introduced within the past month, we want to use another background color, to alert our customers to this new hot product.

    We could solve this in our binding perhaps (let's just assume that is easy), but we should not do that. That would mean the view is deciding when a product is new and hot. It should not.
    The only thing the view should do is create the two visual representations of products and use a datatemplate selector to decide which is hot or not. The datatemplate selector could be injected by our controller. Another way to solve this, is for the controller to put this information in the ViewModel itself. Like, add a boolean 'new' which the view uses.

    If you do not do it this way, and you are embedding logic inside of your view, you will quickly end up with scattered logic, never knowing where something is defined. Changing rules becomes hard and your application will break at some point.
    Now, I understand, and have done many times, that sometimes you just do not have the time to do it right. But always remember that in the long run, you will get burned. Try to setup a situation where it is easy to do the right thing, by making it easy to use datatemplate selectors or use the viewmodel.

    View decoupling

    MVC advocates not letting your view have any knowledge whatsoever of the controller. It does this, because tight coupling of the view to the controller will destroy maintainability and flexibility. If you tight couple, you are unable to swap controllers or views. Most importantly, if you couple the view to the controller (by making it call specific methods on the controller), it becomes harder to maintain/refactor.

    There are certainly approaches that do couple view to controller. If you look at the very powerful Caliburn framework, you will see that the framework has 'action messages' that directly call methods on the controller. I have yet to work with that extensively, so I can not be sure, but it feels to me there should be a very explicit layer between view and controller, which defines how the view will communicate with the controller.

    Our goals in this project are to use the tools WPF provides us to communicate with the rest of the system. We do so with Commands.
    A command can be seen as a message that is passed upward (and downward) the visual tree. Since our adapter lives just above the view and is part of the visual tree, it will have the opportunity to react to the command.

    When building a view, you should also explicitly define all the interactions that view expects to have with the outside world. Do that in a static class like so:

        public static class ImportantWizardInteractions
        {
            public static readonly RoutedUICommand Next;
            public static readonly RoutedUICommand Back;

            public static readonly RoutedUICommand GotoClientScreen;
            public static readonly RoutedUICommand GotoAdresScreen;
            public static readonly RoutedUICommand GotoRoleScreen;
            public static readonly RoutedUICommand GotoCarScreen;

            public static readonly RoutedUICommand Save;
            public static readonly RoutedUICommand SaveYes;
            public static readonly RoutedUICommand SaveNo;


            static ImportantWizardInteractions()
            {
                Next = new RoutedUICommand("Next", "Next", typeof(ImportantWizardInteractions));
                Back = new RoutedUICommand("Back", "Back", typeof(ImportantWizardInteractions));

                GotoClientScreen = new RoutedUICommand("GotoClientScreen", "GotoClientScreen", typeof(ImportantWizardInteractions));
                GotoAdresScreen = new RoutedUICommand("GotoAdresScreen", "GotoAdresScreen", typeof(ImportantWizardInteractions));
                GotoRoleScreen = new RoutedUICommand("GotoRoleScreen", "GotoRoleScreen", typeof(ImportantWizardInteractions));
                GotoCarScreen = new RoutedUICommand("GotoCarScreen", "GotoCarScreen", typeof(ImportantWizardInteractions));

                Save = new RoutedUICommand("Save", "Save", typeof(ImportantWizardInteractions));
                SaveYes = new RoutedUICommand("SaveYes", "SaveYes", typeof(ImportantWizardInteractions));
                SaveNo = new RoutedUICommand("SaveNo", "SaveNo", typeof(ImportantWizardInteractions));


            }
        }

    By being explicit about your interactions like this, you will be able to unit test more easily as well.

    Use in your view like this:

    <Button Command="{x:Static local:ImportantWizardInteractions.GotoClientScreen}">Client</Button>

    A command is great for buttons and other stuff, but how do you do for instance communicate that a customer was selected from a listview?

    1. well, you bind to a selectedCustomer property hopefully, and when the customer was selected, that property changed on the viewmodel. The controller might pick that up.
    2. More explicitly though: do use the SelectedItemChanged event and use the codebehind of your view as a translation layer to talk to the outside world:
    3.         private void ListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
              {
                  // send a command
                  CustomerQueueInteractions.SelectNewCustomer.Execute(e.AddedItems, this);
              }

    You can call me on that. It's not a very elegant solution. I'd rather be able to do away with the codebehind of a view entirely. But using the codebehind is actually fine: it is part of the view, and it should not be allowed to do anything else than to act as a translator for view specific things to commands.

    So, how to show a view

    Well, building a view is nothing else than just deriving from usercontrol and doing your thing. Using commands and going wild on the visuals. (try to animate everything!!! your client loves it).

    It depends now how you want to show it.

    1. Let's say your building a project where you don't care about fancy composition and pluggable modules in your application, and you just want your shell to show your view. The shell might have the following code:
      <c:GenericWorkflowAdapter WorkflowController="{x:Type logic:AControllerForYourView}" >
         
      <v:YourView/>
      </c:GenericWorkflowAdapter>

      I am assuming you do want a controller around your view.

      Here a controller is instantiated and it's content is set to your view. Easy.
    2. Let's say we want our controller to choose what view it uses. That seems to me to be the nicest way to go about it. We will again put a controller in the visual tree, but will not set a view already:

      1. <c:GenericWorkflowAdapter WorkflowController="{x:Type logic:ImportantClientWizard}" />

      Then, in the workflow, we might use some fancy logic to determine which view we will show (perhaps looking at the role of the user). To actually set a view, we will use the SetMainContentActivity. Drag that to the canvas and select a type.

      image

      Selecting a type is easy, because of the typebrowser I included:
      image 

    3. Yet another way, that is suitable for 'subviews', is to define a contentpresenter on some view anywhere:
    4. <ContentPresenter 
      ContentTemplate="{DynamicResource CurrentWizardScreen}" />


    And use the InjectViewAsDataTemplate activity in a controller to place a contenttemplate in the resources section with the same resourcekey.
    image

     

    I'll follow up with another take on decoupling the view from the controller, by looking at the SetDataContext activity and talking a bit more about the viewmodel.

    Thursday, February 21, 2008 11:57:02 AM (Romance Standard Time, UTC+01:00)  #    Comments [4]  |  Trackback
     Wednesday, February 20, 2008

    This is the second of a series about how to go about using postcompilation in your solutions. You can read it as a tutorial on how to use PostSharp. I am very much a new to that framework, but the power it provides could seriously change how you build your applications. While working on the EF contrib project, I had to dive into PostSharp, and I hope to share some of the things I learned along the way.

    This post introduces the first real step I took: the compound aspect.

    The full table of contents:

  • Introducing Entity Framework Contrib- Easy IPoco implementation V 0.1
  • Part II, Postsharp Core versus Postsharp Laos
  • Part III, the compound aspect
  • Part IV, the PocoInterfaceSubaspect
  • Part V, hooking up the weaver
  • Part VI, the EdmScalarWeaver
  • Recap

    We wish to create an attribute that can be placed on top of our ordinary Poco class, that will magically transform it into a class that implements the 3 IPoco interfaces. These are needed by the Entity Framework to do it's work. We will use PostSharp to do this.
    Post 1 introduced the project and post 2 introduced PostSharp.

    The Compound aspect

    I have created an attribute class that can be placed on top of other classes, like so:

        /// <summary>
        /// <para>
        /// Attribute that can be used to decorate normal POCO classes with. It is used to start off a post compilation phase
        /// that will modify the IL of the class. After this phase, the class will implement:
        /// <list type="">
        /// <item>INotifyPropertyChanged</item>
        /// <item>IEntityWithChangeTracker</item>
        /// <item>IEntityWithKey</item>
        /// <item>IEntityWithRelationships</item>
        /// </list>
        /// </para>
        /// <para>
        /// It will also place EDMScalarattributes on your properties.
        /// </para>
        /// <para>This results in a type that is completely ready for consumption by the EntityFramework</para>
        /// </summary>
        [AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = false)]
        [MulticastAttributeUsage(MulticastTargets.Class, AllowMultiple = false)]
        public sealed class PocoAttribute : CompoundAspect
        {
    ... implementation
        }

    As you can see it inherits from the compound aspect class, from the PostSharp.Laos assembly.

    The compound aspect basically allows you to define other aspects to do the job for you. This is very nice when you want to do more things, but only want to use one aspect.

    By overriding the ProvideAspects method, we can add our other aspects:

      1         public override void ProvideAspects(object element, LaosReflectionAspectCollection collection)
      2         {
      3             // Get the target type.
      4             Type targetType = (Type)element;
      5
      6             // implement the INotifyPropertyChanged interface on the class
      7             collection.AddAspect(targetType, new AddNotifyPropertyChangedInterfaceSubAspect());
      8             // implement the three IPOCO interfaces on the class
      9             collection.AddAspect(targetType, new PocoInterfacesSubAspect());
    10             // inspect the complete class and add EDM scalar attributes to the properties
    11             collection.AddAspect(targetType, new EDMAttributesSubAspect(this.EDMContainerName, Name, NamespaceName, PathToConfigFile));
    12
    13             // iterate the properties
    14             foreach (PropertyInfo property in targetType.UnderlyingSystemType.GetProperties())
    15             {
    16                 if (property.DeclaringType == targetType && property.CanWrite)
    17                 {
    18                     MethodInfo method = property.GetSetMethod();
    19
    20                     if (!method.IsStatic)
    21                     {
    22
    23                         // throw notifypropertychanged events
    24                         collection.AddAspect(method, new OnPropertySetNotifyPropertyChangedSubAspect(property.Name, this.AspectPriority));
    25
    26                         // TODO: possibly refactor to only include edm properties
    27                         // call the changetracker
    28                         collection.AddAspect(method, new OnPropertySetChangeTrackSubAspect(property.Name, this.AspectPriority));
    29                     }
    30                 }
    31             }
    32         }

    As you can see, on line 4 I cast the element parameter to a type. That is the type we have adorned with our attribute (your 'Person' Poco class, for instance). Then, I specify that I want 3 other aspects to work on this type!

    • The AddNotifyPropertyChangedInterfaceSubAspect, will implement the INotifyPropertyChangedInterface. (note: this aspect is added just for simplicity, it has nothing to do with IPoco, so I might remove it).
    • The PocoInterfaceSubAspect, will implement the 3 interfaces (see following post)
    • The EDMAttributesSubAspect, will put EDMScalar attributes on top of our properties, needed by EF to do it's job

    After that, I loop through the properties in our targetType and add aspects to their setters. These will inject methods into the setters to throw the PropertyChanged event and let the EF changetracker know that the property was changed.

    That's all the work this compound aspect does. It just provides aspects to the correct codeblocks. The real work is done inside of these aspects and will be explained in following posts.

    Wednesday, February 20, 2008 1:34:36 PM (Romance Standard Time, UTC+01:00)  #    Comments [0]  |  Trackback