VS2010, Silverlight 3 and Windows 7 - can't convert SL3 project

My adventures started when I was notified that my Windows 7 beta was going to expire in 2 days.  While I continued to work on it I created a "production" development box; I've learned my lesson - don't install Beta on a production box...

With my production box functional I now had to create a Beta box which has all the cool stuff like VS2010, Silverlight 3, C# 4.0, etc.

The problem was with a fresh install you cannot convert Silverlight projects - I needed my PRISM projects (which I won't code without) and was dismayed to find out that everything "appeared" to work but the project never showed up.   The following is the fix! 

The following folder

C:\Program Files (x86)\MSBuild\Microsoft\Silverlight

Only has a v3.0 folder. I copy/pasted this folder and renamed the copy to v2.0 and the project would successfully appear after conversion.

 

 


Tags: ,
Categories: WCF


Actions: E-mail | Permalink |  Grammar/Typo/Better way? Please let me know

VS2010 - The ServicePointManager does not support proxies with the https scheme

I created a Codeplex project for a Visual Studio 2010 solution and was greated with the error "The ServicePointManager does not support proxies with the https scheme".

When you Google for "VS2010 Codeplex" you will find the following link at the top of the list:

http://coolthingoftheday.blogspot.com/2009/05/have-vs2010-beta-1-trying-to-connect-to.html

Where I was very happy to find a solution I was disappointed that it was only partial; it didn't provide the actual registry entries.  I found a blog that actually provided the registry settings and was disappointed when it didn't work.  

So I continued my search and was glad to find the following blog because it actually provided the commands necessary to automatically add the required registry entry.   It seemed to match what I did manually so I trust I made a typo somewhere.

The following link fixes it:

http://blogs.msdn.com/ablock/archive/2009/05/20/for-tfs-2010-beta-1-resolving-tf31001-the-servicepointmanager-does-not-support-proxies-with-the-https-scheme.aspx

I deleted my entries and ran the above commands for a 64bit environment and "walla!" I was able to connect to my codeplex project using VS2010!

For you 64bit folks the following batch file may save you a few steps

tfsFix.bat (267.00 bytes)

Note: In case their site is down at the time you need it I provide an excerpt (important stuff) from the above link:

If you are receiving the TF31001 error, you should be able to resolve this issue by running the following commands:

On all machine:

reg add hklm\SOFTWARE\Microsoft\VisualStudio\10.0\TeamFoundation\RequestSettings /v BypassProxyOnLocal /t REG_SZ /d False

reg add hklm\SOFTWARE\Microsoft\TeamFoundationServer\10.0\RequestSettings /v BypassProxyOnLocal /t REG_SZ /d False

 

Additionally on a 64-bit machine:
reg add hklm\SOFTWARE\Wow6432Node\Microsoft\TeamFoundationServer\10.0\RequestSettings /v BypassProxyOnLocal /t REG_SZ /d False
reg add hklm\SOFTWARE\Wow6432Node\Microsoft\VisualStudio\10.0\TeamFoundation\RequestSettings /v BypassProxyOnLocal /t REG_SZ /d False
  --Aaron

 


Tags: , ,
Categories: Visual Studio 2010


Actions: E-mail | Permalink |  Grammar/Typo/Better way? Please let me know

ISO15926 - Step 1: Semantic Web and the SPARQL protocol

As a member of the ISO 15926 IDS-ADI (international) development team for the IRING project I have to ramp up on the various technologies involved - Step 1 of what will probably be an ongoing series is getting the Joseki Service installed so we can start talking SPARQL.

RDF Primer    SPARQL Query Language for RDF

How do  you eat an elephant "one bite at a time" Smile and ISO15926 can be quite the elephant. So where do you start?  I'm told by the gurus that the place to start is by playing with the SPARQL Endpoint and SPARKQL Protocol http://www.joseki.org/.  To do this you will have some installation steps to comply with.

If you go to the Documentation | Quickstart link you will be greeted with the following:

  • Unzip the distribution.
  • cd to the root of the distribution.
  • Linux/Cybgwin: Make the scripts executable (e.g. chmod u+x bin/*)
  • Set the JOSEKIROOT environment variable to the location of the installation.
  • Run the script rdfserver (bin/ or bat/). This will run an HTTP server on port 2020.
  • Go to http://localhost:2020/
  • It really is as simple as that but much knowledge is assumed so I'll fill in the blanks with step-by-step information

    1. Ensure you have JAVA installed - it can be downloaded from http://java.com/

    2. Unzip the distribution - for the sake of these instructions I downloaded and unziped the "distribution" to C:\Projects\Joseki-3.3.0

    Note: this is the Windows Environment - I am using Windows 7

    3. Set the JOSEKIROOT environment variable to the location of the installation as follows:

    + Click on  Start | Control Panel | System and click the "Environment Variable" Button

      + Click "New" and enter the applicable information as shown below:

     + Now we're going to edit the "Path" environment variable and append the path to our newly installed Java application.  I am have an X64 system so it will have the c:\program files (x86) path.  Note that paths are delimited by a semicolon so be sure to prefix your path with a semicolon.

     

    4. Run the script rdfserver (bin/ or bat/). This will run an HTTP server on port 2020.

    If you attempt to execute the rdfserver.bat file directly (in the bin folder) the screen will flash before you.  Placing a "pause" command at the end of the batch file will result in the following:

    This will require you to launch a "Command Prompt" and then perform a Change Directory (CD) command to access the command. i.e.,

    CD C:\Projects\Joseki-3.3.0

    This of course assumes you are on the C: drive.  If you are not type in the following and you will be

    C: <ENTER>

    Note below in my screen shot that I went to the actual "Bin" folder.  I then do a CD .. which tells DOS to backup one folder effectively placing me in the proper folder.  I then can execute the RDFServer.bat file using the following command:

    BIN\RDFServer.bat

    Which effectively loads my SPARKL Server for Jena

    With your web server up and running (shown above) you can now load your browser and go to the URL

    http://localhost:2020 and see the following - you are ready to play!


    Tags: , ,
    Categories: ISO15926


    Actions: E-mail | Permalink |  Grammar/Typo/Better way? Please let me know

    Mobile Framework for Mobile 5.0 - Managing Control State with ControlContainer

    Preceived performance is more significant then actual performance.  If a user clicks a Login button and nothing happens within the first few second they'll click it again thinking perhaps it didn't register.  If a few more seconds pass they may wonder if it locked up.  

    If however the button text changes immediately showing that it is checking their credentials (against a backend database) and then a second later changes again letting the user know that it is loading data, which may be from multiple data sources (in the case of the example below Facility, Level of Care and Patient data) the perceived performance will be high.  
    See video clip (no audio) 

    The following ObjectContainer class allows us to easily manage a Button's state (Text and Enabled properties) by taking advantage of the IDisposable interface:

    using System;
    
    using System.Linq;
    
    using System.Collections.Generic;
    
    using System.Text;
    
    using System.Windows.Forms;
    
     
    
    namespace Library.Mobile.Interface.Containers
    
    {
    
        /// <summary>
    
        /// Manages object state, i.e., if T is Button then the button
    
        /// will be disabled and the button text will be stored.  When
    
        /// the control disposes the text will be restored and the button
    
        /// reenabled.
    
        /// </summary>
    
        /// <typeparam name="T"></typeparam>
    
        public class ObjectContainer<T> : IDisposable
    
        {
    
            public T Data { get; set; }
    
            public string Text { get; set; }
    
     
    
            /// <summary>
    
            /// Constructor - sets up T so that it can be restored on dispose
    
            /// </summary>
    
            /// <param name="control">The control.</param>
    
            /// <param name="text">The text.</param>
    
            public ObjectContainer(T control, string text)
    
            {
    
                Data = control;
    
     
    
                // Cast T to object so we can work withit
    
                object data = Data;
    
     
    
                if (control is Button)
    
                {
    
                    Text = ((Button)data).Text;     // Store button text
    
                    ((Button)data).Enabled = false; // Disable button
    
                    ((Button)data).Text = text;     // Set new button text
    
                }
    
                Application.DoEvents();
    
            }
    
            /// <summary>
    
            /// Performs application-defined tasks associated with freeing, releasing,
    
            /// or resetting unmanaged resources.
    
            /// </summary>
    
            public void Dispose()
    
            {
    
                // Cast T to object so we can work withit
    
                object data = Data;
    
     
    
                if (Data is Button)
    
                {
    
                    ((Button)data).Text = Text;     // Restore button text
    
                    ((Button)data).Enabled = true// Enable button
    
                }
    
                Application.DoEvents();
    
            }
    
        }
    
    }
    

    Below we'll modify the button text, as business logic dictates, and when we're done the original state will be automagically restored:

    Note that on the breakpoint for line 56 that we still have our standard "Login" text for our login button. 

    On the very next instruction (line 61) we see that we've changed our button text to "Verifying Login.."; reference arrows below:

    With a successful login we change our button text again, on Line 73, to show that we are logged in and loading Tom's patient data:

    At this point we raise the OnLoginSuccess event which is subscribed to in the main view (we are inside of a Login UserControl).   Below we show the new modal form that is loaded.  We haven't hit line 79 yet; as far is the Login control is concerned we are still on line 74.

    Once OnLoginSuccess is exited (line 74 below) and we exit the scope of the using statement (Line 61 thru 78) our ObjectContainer.Dispose event will fire.  So when we hit line 79 the ObjectContainer's Dispose event will have effectively restored the button state. 

    See video clip (no audio)  In this video clip you saw the button text being changed beyond the scope of what was being shown above.  Each user control (usrFacility, usrLevelOfCare and usrPatient) on the Main view is passed a PatientDataEventArgs during it's OnViewReady() event where it gets a reference to the usrLogin control and updates the login view's button text.   Below is the typical user control presenter:


    Tags:
    Categories: Compact Framework


    Actions: E-mail | Permalink |  Grammar/Typo/Better way? Please let me know

    Mobile Framework for Mobile 5.0 - Resolving unmapped Interface returns null

    Error Subclassing controls - workaround HERE

    UPDATE: Mobile 6 Framework has an excellent DI container!   As of this writing you have to download it from the Source Code tab (it isn't in the release) but in the download they provlde performance test and the Mobile container out performs all others to include Unity.

    http://mobile5framework.codeplex.com/  <= Mobile 5 Framework source code
    http://www.codeplex.com/compactcontainer  <= Dependency Injection for Compact Framework 

    Side note: one thing I really love about VSS, that we can't easily do in VSTS, is share projects between solutions.  For example, my production application (Electronic Patient Record Medical System) uses the same libraries as my Mobile 5 Framework (Codeplex) project.  So as I update/fix my framework it is immediately available for my codeplex project.  Even though my development environment is managed by VSS the interesting (cool/strange) thing is my Codeplex project is a VSTS solution that includes my shared VSS projects - and it doesn't complain - it works in both environments :)  

    On to the real information:   I updated the CompactContainer today to return null if an interface is not Type Mapped, i.e., there is not an entry in the configuration file to support the type being resolved.

    The alternative would be to throw an exception like other DI containers, which I trust a lot of thought went into.  I opted to return null for reasons demonstrated by the following code, e.g., if on line 37 my ILogger cannot be resolved (as it won't because it wasn't configured) line 38 will still result in a logger.

    Why?  The Logger setter on line 24 set it to the value null, returned by Container.Resolve<ILogger>(), however line 20 sees the null which results in DefaultLogger() being instantiated and then returned on line 22. 

    So the lazy instantiation of Logger ensures there will always be a logger HOWEVER if I did configure ILogger in my configuration file then it will be used.   Throwing Exceptions involve a performance hit which we really want to avoid in the Compact Framework.

    NOTE:  I used .NET 3.5 extensions to substitute Resolve (on line 37 above) for the actual CompactContainer syntax shown on line 369 below.

    My goal is to leave existing functionality of the CompactContainer intact, for backwards compatibility, while adding new features.   The image following this one shows the result(s) of unit test against the CompactContainer's original code.

    The following shows the unit test using CompactContainer35 running against the original objects provided in the TestDI demo application (using it's config.xml and config2.xml contents):

    Then of course we have our unit test for our new Interface injection: 

    /// <summary>
    
    /// Determines whether this instance [can inject interface with 
    
    /// configured immplmentation].
    
    /// </summary>
    
    [TestMethod]
    
    public void CanInjectInterfaceWithConfiguredImmplmentation()
    
    {
    
        // ConfigFilename is pulled from the baseclass - it is
    
        // identical to the CompactContainer CONFIG.XML with used
    
        // with TestDI with exception of Filename and appended Properties
    
        CompactContainer.CompactConstructor.DefaultConstructor
    
            .AddDefinitions(ConfigFilename);
    
     
    
        // Resolve interface based on the following ObjectDefinition
    
        // in the configuration file (in AppBaseTest)
    
        //----------------------------------------------------------------------
    
        // <ObjectDefinition Name='TypeMappings'>
    
        //   <Property 
    
        //      Name='IMockDIObject' 
    
        //      SetWithNewType='CompactContainer.Tests.MockObjects.MockDIObject' 
    
        //      FileName='CompactContainer.Tests.dll'/>
    
        // </ObjectDefinition>
    
        //----------------------------------------------------------------------
    
        IMockDIObject mockObj = Container.Resolve<IMockDIObject>();
    
     
    
        // Assert that we successfully resolved our interface
    
        List<MockUser> userList = mockObj.GetUserList(this, EventArgs.Empty);
    
        Assert.AreEqual(2, userList.Count, "There should be two Mock Users");
    
        Assert.AreEqual("Bill", userList[0].FirstName);
    
        Assert.AreEqual("Diane", userList[1].FirstName);
    
     
    
    }
    

    Tags: , ,
    Categories: Compact Framework | CompactContainer


    Actions: E-mail | Permalink |  Grammar/Typo/Better way? Please let me know

    Mobile Framework for Mobile 5.0 with a Compact (DI) Container

    Note: In this blog I show how to deserialize XML into an object that has child objects. 

    Although the core requirements for this phase of my current project will result in a Mobile/PDA application being completed by next week, I struggle having to work without a DI container (been real spoiled by Unity on the Web and Desktop side of the house).    

    Preliminary research led me to an excellent (beta) DI container on codeplex (http://www.codeplex.com/compactcontainer/) by Mariano Julio Vicario.  Although it doesn't yet have constructor injection it provides setter injection which means I can inject my business logic layer as well as other reusable services.  Important since I've created a very dynamic framework.

    I ran into two snags... the first was that it doesn't support .NET 3.5 - the serialization crashes and burns when I plugged it into a prototype application (source attached) that utilizes my framework.  I should clarify that Mariano's TestDI demo does run on the .NET 3.5 framework "as is" however it uses the .NET 2.0 assemblies.  When you create a new project and attempt to utilize the CompactContainer is where you will run into problems. 

    The second was that the P&P folks released a new Mobile framework late Feb which replaced the CAB with a DI container.  Naturally I jumped on that, even at risk of scraping my framework, but was dismayed to see that it only supports Mobile 6.1 - so I ordered my new HP IPAQ 211 w/1gig ram but it won't be here until next week (about the time my application will be completed).   I'm chomping at the bit to play with the new Mobile framework....

    So Mariano's DI container it is it for my current framework but I still had to get past the first snag - this blog has the details :)

    I opted to go with LINQ to SQL and replaced the deserialization process with it.  Below is the line of code I changed to make the switch.

    The magic is done with the new Extension class which is referenced at the top of the file as follows:

    using CompactContainer.Tools;
    
    using System.Xml.Linq;
    
     
    
    // BillKrat.2009.03.18 - provide LINQ to XML extensions
    
    using CompactContainer.Extensions;
    


    The following Unit Test shows it in action:

    using System.Collections.Generic;
    
    using System.Linq;
    
    using Microsoft.VisualStudio.TestTools.UnitTesting;
    
    using System.Xml.Linq;
    
    using CompactContainer.ConfigurationObjects;
    
    using CompactContainer.Extensions;
    
     
    
    namespace CompactContainer.Tests
    
    { 
    
        /// <summary>
    
        /// Summary description for UnitTest1
    
        /// </summary>
    
        [TestClass]
    
        public class CompactContainerFixture
    
        {
    
            public CompactContainerFixture() {  }
    
     
    
            private XElement config = XElement.Parse (
    
                @"<?xml version='1.0' encoding='utf-8' ?>
    
                <CompactContainer xmlns='http://tempuri.org/ConfigurationSchema.xsd'>
    
                  <Context Name='default'>
    
                    <ObjectDefinition Name='Demo' 
    
                                      Type='PasswordManager.Login.LoginViewPresenter' 
    
                                      Singleton='false' 
    
                                      FileName='PasswordManager.exe'>
    
                        <Property Name='Str' 
    
                                  Set='Hi Set of String' />
    
                        <Property Name='Inte' 
    
                                  Set='28' />
    
                        <Property Name='Something' 
    
                                  SetWithNewType='TestDI.BehaviourISomething' 
    
                                  FileName='PasswordManager.exe' />
    
                        <Property Name ='Obj2' 
    
                                  SetWithObjectDefinition='Object2'/>
    
                    </ObjectDefinition>
    
                    <ObjectDefinition Name='Object2' 
    
                                      Type='PasswordManager.Main.MainViewPresenter' 
    
                                      Singleton='true' 
    
                                      FileName='PasswordManager.exe'>
    
                      <Property Name='Inte2' Set='98' />
    
                    </ObjectDefinition>
    
                  </Context>
    
                </CompactContainer> ");
    
     
    
            /// <summary>
    
            /// Determines whether this instance [can read configuration file].
    
            /// </summary>
    
            [TestMethod]
    
            public void CanReadConfigurationFile()
    
            {
    
                CContainer container = new CContainer();
    
     
    
                // Uses new CompactContainerExtensions
    
                container.Items = config.GetContext();
    
     
    
     
    
                Assert.AreEqual(1, container.Items.Length, 
    
                    "There should only be one context");
    
                Assert.AreEqual(2, container.Items[0].ObjectDefinitions.Length, 
    
                    "There should be two Object Definitions");
    
     
    
                ObjectDefinition demo = container.Items[0].ObjectDefinitions[0];
    
                ObjectDefinition object2 = container.Items[0].ObjectDefinitions[1];
    
     
    
                Assert.AreEqual("default", container.Items[0].Name,
    
                    "The context name should be 'default'");
    
     
    
                Assert.AreEqual("Demo", demo.Name);
    
                Assert.AreEqual("PasswordManager.Login.LoginViewPresenter", demo.Type);
    
                Assert.IsFalse(demo.Singleton);
    
                Assert.AreEqual("PasswordManager.exe", demo.FileName);
    
                Assert.IsNotNull(demo.Properties.First<Property>(
    
                    p => p.Set.Contains("Hi Set of String")));
    
                Assert.IsNotNull(demo.Properties.First<Property>(
    
                    p => p.Set.Contains("28")));
    
                Assert.IsNotNull(demo.Properties.First<Property>(
    
                    p => p.SetWithNewType.Contains("TestDI.BehaviourISomething")));
    
                Assert.IsNotNull(demo.Properties.First<Property>(
    
                    p => p.FileName.Contains("PasswordManager.exe")));
    
                Assert.IsNotNull(demo.Properties.First<Property>(
    
                    p => p.SetWithObjectDefinition.Contains("Object2")));
    
     
    
                Assert.AreEqual("Object2", object2.Name);
    
                Assert.AreEqual("PasswordManager.Main.MainViewPresenter", object2.Type);
    
                Assert.IsTrue(object2.Singleton);
    
                Assert.AreEqual("PasswordManager.exe", object2.FileName);
    
                Assert.IsNotNull(object2.Properties.First<Property>(
    
                    p => p.Name.Contains("Inte2") && p.Set.Contains("98")));
    
            }
    
        }
    
     
    
     
    
    }
    

    The new Extension class follows:

    using System.Collections.Generic;
    
    using CompactContainer.ConfigurationObjects;
    
    using System.Xml.Linq;
    
     
    
    namespace CompactContainer.Extensions
    
    {
    
        /// <summary>
    
        /// 
    
        /// </summary>
    
        public static class XElementExtensions
    
        {
    
            /// <summary>
    
            /// Attrs the STR.
    
            /// </summary>
    
            /// <param name="element">The element.</param>
    
            /// <param name="fieldName">Name of the field.</param>
    
            /// <returns></returns>
    
            public static string AttrStr(this XElement element, string fieldName)
    
            {
    
                object data = element.Attribute(fieldName);
    
                return data == null ? "" : element.Attribute(fieldName).Value;
    
            }
    
     
    
            /// <summary>
    
            /// Attrs the bool.
    
            /// </summary>
    
            /// <param name="element">The element.</param>
    
            /// <param name="fieldName">Name of the field.</param>
    
            /// <returns></returns>
    
            public static bool AttrBool(this XElement element, string fieldName)
    
            {
    
                object value = element.Attribute(fieldName);
    
                return value == null ? false :
    
                    "true".Contains(element.Attribute(fieldName).Value.ToLower());
    
            }
    
     
    
            /// <summary>
    
            /// Gets the properties.
    
            /// </summary>
    
            /// <param name="prop">The prop.</param>
    
            /// <returns></returns>
    
            public static Property[] GetProperties(this XElement prop)
    
            {
    
                List<Property> propList = new List<Property>();
    
                foreach (XElement pr in prop.Elements())
    
                    propList.Add(new Property
    
                    {
    
                        FileName = pr.AttrStr("FileName"),
    
                        KeyType = pr.AttrStr("KeyType"),
    
                        ListType = pr.AttrStr("ListType"),
    
                        Name = pr.AttrStr("Name"),
    
                        Set = pr.AttrStr("Set"),
    
                        SetDictionary = pr.AttrStr("SetDictionary"),
    
                        SetList = pr.AttrStr("SetList"),
    
                        SetWithNewType = pr.AttrStr("SetWithNewType"),
    
                        SetWithObjectDefinition = pr.AttrStr("SetWithObjectDefinition"),
    
                        ValueType = pr.AttrStr("ValueType")
    
                    });
    
                return propList.ToArray();
    
            }
    
     
    
            /// <summary>
    
            /// Gets the object definitions.
    
            /// </summary>
    
            /// <param name="objDef">The obj def.</param>
    
            /// <returns></returns>
    
            public static ObjectDefinition[] GetObjectDefinitions(this XElement objDef)
    
            {
    
                List<ObjectDefinition> odList = new List<ObjectDefinition>();
    
                foreach (XElement od in objDef.Elements())
    
                    odList.Add(new ObjectDefinition
    
                    {
    
                        FileName = od.AttrStr("FileName"),
    
                        Name = od.AttrStr("Name"),
    
                        Properties = od.GetProperties(),
    
                        Singleton = od.AttrBool("Singleton"),
    
                        Type = od.AttrStr("Type")
    
                    });
    
                return odList.ToArray();
    
            }
    
     
    
            /// <summary>
    
            /// Gets the context.
    
            /// </summary>
    
            /// <param name="context">The context.</param>
    
            /// <returns></returns>
    
            public static Context[] GetContext(this XElement context)
    
            {
    
                List<Context> contextList = new List<Context>();
    
                foreach (XElement child in context.Elements())
    
                    contextList.Add(new Context
    
                    {
    
                        Name = child.AttrStr("Name"),
    
                        ObjectDefinitions = child.GetObjectDefinitions()
    
                    });
    
                return contextList.ToArray();
    
            }
    
        }
    
    }
    

    The following is a short screencast (no audio) that shows the framework in action (the virtual methods in PresenterBase provide hooks into events that are not normally available, i.e., OnLoad for user controls) :
    http://global-webnet.net/Webcast/PasswordManager.htm 

    http://mobile5framework.codeplex.com/ <= Source code

    MobileFlow.txt (5.97 kb)  <= Shows the flow of events for Views and their User Controls (best viewed in notepad with Arial 10 font - alignment)

     


    Tags: , ,
    Categories: Compact Framework


    Actions: E-mail | Permalink |  Grammar/Typo/Better way? Please let me know

    Visual Studio 2008 can't deploy to Emulator - Stops responding

    Ran into a situation when deploying to the Emulator with Visual Studio 2008, Windows 7 and the compact framework.  Everytime I attempted to deploy the emulator would have the spinning circle (center of image below)



    Visual Studio would stop responding and generate an error message. 

     

    I had reset my computer and received the same results. 

    Everything had been working without issue so I undid prior code changes, rebuilt and still my Visual Studio would lock up and my Emulator would stay with the spinning circle.

    Since the emulator was still running I treated it like a Device and stopped the running program and tried again.  Still locking up Visual Studio.  I then did a Hard Reset on the emulator and walla!  I was back in business - Visual Studio 2008 was happy again.


    Tags: ,
    Categories: Compact Framework


    Actions: E-mail | Permalink |  Grammar/Typo/Better way? Please let me know

    Mobile / Compact Framework UserControl DesignMode null in constructor

    Mobile Development has proven to be quite the chore.  Nothing like getting all of your code in place after hours of work to find your designer is broken and there isn't a clue as to why.  Countless hours lost because you can't get the designer to show your Mobile Form, and YOU HAVE TO BE ABLE TO UPDATE IT, with your only option to "undo checkout" (source control) and start over.   I learned to try "all" my views/forms regularly before I go too far...

    If you are like me and this is costing you days of development and you are starting to think you can't use UserControls or derive from base classes because the Visual Studio Designer (I'm using VS2008) is too fragile, there is a solution!  It follows on line 10 below:

        1         /// <summary>

        2         /// Constructor

        3         /// </summary>

        4         public usrPatients()

        5         {

        6             InitializeComponent();

        7 

        8             // The ParentChanged += that follows will crash the

        9             // designer (Mobile designer is fragile)

       10             if (DesignMode.IsTrue)

       11                 return;

       12 

       13             // So our UserControl can have an OnLoad event - this

       14             // event fires when the parent form adds the user control

       15             ParentChanged += (sender, e) => { OnLoad(sender, e); };

       16         }

    Note: before you run off and try to type in the code above please know DesignMode is a class I wrote with a static property IsTrue (keep reading..) 

    So you google the problem CLICK HERE and the first link on the list gives you a clue that you are in trouble - emphasis on "There is no LicenseManager in Compact Framework", you also learn that this.DesignMode doesn't work in UserControls, you learn Site.DesignMode is always null in constructors, you learn the directives don't work - the most important thing you learn is you need to return after InitializeComponent() yet Visual Studio doesn't support a way to do this in a VS2008 UserControl constructor. 

    I think I actually chuckled when I saw the above because that is where I was living, I was quickly falling behind the power curve and was tired of rewriting code over and over.  The following was my form with three user controls (top three containing dropdown with buttons).

    The pattern I have been following the last couple of weeks follows: I'd do simple infrastructure work on my user control, would have everything working during runtime, and then would have to stop to do my dreaded Form/View check (clicking on every single control) and wouldn't you know it - I'd get to a form that uses my control and I'd get the following error:

    I was locked out of my form AGAIN!!!   This was becoming a critical issue - I was dead in the water again and it was time to find out why and fix it.

    Are you where I was?  Rest assured - I have your answer :)  Keep reading...

    This was a critical error because unlike some of the other errors I've encountered, where they give you a clue and you can go to the offending line of code in the control and fix it - the above tells you nothing.

    So to recap... after much research I came to the conclusion that user controls *have* to return immediately after InitializeComponent() or the successive commands could threaten parent forms from being able to build themselves in the designer.   The problem is no available solutions work - especially for the Compact Framework with code in the constructor.

    For example,  I have an MVP infrastructure (Model-View-Presenter) in place where my Presenter's baseclass wires up the MVP.   To make this happen (automagically) I have to have a Load() event in my user control - which doesn't exists - so I created one tapping into the ParentChanged event on line 15 below.

     

        1         /// <summary>

        2         /// Constructor

        3         /// </summary>

        4         public usrPatients()

        5         {

        6             InitializeComponent();

        7 

        8             // The ParentChanged += that follows will crash the

        9             // designer (Mobile designer is fragile)

       10             if (DesignMode.IsTrue)

       11                 return;

       12 

       13             // So our UserControl can have an OnLoad event - this

       14             // event fires when the parent form adds the user control

       15             ParentChanged += (sender, e) => { OnLoad(sender, e); };

       16         }

    This works now and I'm allowed to use my infrastructure without breaking my Form in the designer!  The usrPatientsPresenter(this, args) statement on line 39 completely wires up my View, Presenter and Model ensuring the Parent form will be notified (w/data) when an event in the user control happens: 

       20         private usrPatientsPresenter _presenter;

       21         public IPresenterBase Presenter

       22         {

       23             get { return _presenter; }

       24             set { _presenter = (usrPatientsPresenter) value; }

       25         }

       26 

       27         /// <summary>

       28         /// Overridden so we have hook into something we can use

       29         /// as a load event

       30         /// </summary>

       31         /// <param name="e"></param>

       32         protected void OnLoad(object sender, EventArgs e)

       33         {

       34             // Instantiate and configure presenter

       35             PatientDataEventArgs args = new PatientDataEventArgs {

       36                 CurrentProviderData =

       37                     ((IViewBase)Parent).Presenter.CurrentProvider

       38             };

       39             _presenter = new usrPatientsPresenter(this, args);

       40             _presenter.cboPatient = this.cboPatient;

       41 

       42             // Subscribe to presenter's event and bubble to form

       43             _presenter.OnNewPatient += (sender1, e1) =>

       44                 { if (OnNewPatient != null)

       45                     OnNewPatient(sender1, e1); };

       46 

       47             // Subscribe to presenter's event and bubble to form

       48             _presenter.OnPatientChanged += (sender1, e1) =>

       49                 { if (OnPatientChanged != null)

       50                     OnPatientChanged(sender1, e1); };

       51         }

    Below is the interface that shows what my Form AND UserControl (view) presenters will consistently have available, i.e., OnViewLoad and more importantly OnViewActivated - since user controls load before the main form does:

        7 namespace Library.Mobile.Interface.Interfaces.Base

        8 {

        9     public interface IPresenterBase

       10     {

       11         event EventHandler<EventArgs> OnPresenterActivated;

       12         ProviderData CurrentProvider { get; set; }

       13 

       14         void OnViewReady(object sender, EventArgs e);

       15         void OnViewSet(object sender, EventArgs e);

       16         void OnViewLoad(object sender, EventArgs e);

       17         void OnViewActivated(object sender, EventArgs e);

       18     }

       19 }

    Now for the answer we've been searching for (drum roll):

        1 using System;

        2 using System.Linq;

        3 using System.Collections.Generic;

        4 using System.Text;

        5 

        6 namespace Library.Mobile.Interface.Base

        7 {

        8     public sealed class DesignMode

        9     {

       10         public static bool IsTrue

       11         {

       12             get { return AppDomain.CurrentDomain

       13                 .FriendlyName.Contains("DefaultDomain"); }

       14         }

       15     }

       16 }

    Please post a link to this Blog if this has cost you countless days of work (as it did me) so we can perhaps save someone else the headaches....

     


    Tags: , ,
    Categories: Compact Framework


    Actions: E-mail | Permalink |  Grammar/Typo/Better way? Please let me know

    Silverlight and WPF - CompositeWPF/Prism supports multi-targeting (single shared codebase)

    Source Code available at http://www.Codeplex.com/SDMS 
    Project Linker Blog w/Webcast HERE  

    A recent Microsoft Codeplex forum interaction had me updating the SDMS application so that the Employee Module and all of it's views were Multi-targeting (worked on both Desktop and Silverlight).  The reasoning follows below: 

    Developer writes "I'm not looking for multi-targeting support, I just want an SL app that uses WCF and is maintainable and testable."

    My response follows:

    I don't think they are mutually exclusive - I believe you may want/need multi-targeting support.   Let me explain by example - I just spent the last couple of hours updating the SDMS application so that the Modules folder is supported under both Desktop and Silverlight.  Why?   "maintainable and testable".   I created a Unit Test for you and checked everything in (been really wanting to do this for a while and this gave me good reason to).

    The key point here is that the "only" code that will be different will be the XAML (Silverlight/WPF) and the actual WCF Service call.  I did however create my Desktop WCF Service using Async communications so you won't find any SILVERLIGHT conditional statements anywhere in the Business Logic Layer or Data Layer (they are one and the same code for both sides).   I should give a plug for the Project Linker (blogged about on my blog site w/webcast); all my time was spent creating empty WPF views and implementing the interface on them.

    [TestMethod]

    public void TestMethod1()

    {

        // IModule does all of the heavy lifting - configures all interfaces

        // so we'll just use it to set things up.

        IModule module = Container.Resolve<IModule>();

        module.Initialize();

     

        // Resolve the EmployeeList Presenter

        EmployeeListPresenter MockView = Container.Resolve<EmployeeListPresenter>();

     

        // Give WCF Service a chance to complete

        Thread.Sleep(2000);

     

        // Cast so we can easily access presentation model

        EmployeePresentationModel model =
                 (EmployeePresentationModel) MockView.Model;

     

        Assert.AreEqual(3, model.EmployeeList.Count,
                       "Employee list should have three records!");

    }


    Note we can put the Testing thread to sleep :)  I just tested everything short of the UI which is databound to the presentation model (nothing to test in the view) all the way through the WCF Service and back.  Since my PresentationModel implements INotifyPropertyChanged I can rest assured my View will work (assuming I did my Binding correctly).

    Let's see what IModule was up to (showing the effectiveness of multi-targeting)

     

     

    public class ModuleEmployee : IModule

    {

        // For class use

        private readonly IUnityContainer container;

        private readonly IRegionViewRegistry regionViewRegistry;

     

        /// <summary>

        /// Constructor : Setup class

        /// </summary>

        /// <param name="container"></param>

        /// <param name="regionViewRegistry"></param>

        public ModuleEmployee(IUnityContainer container,

            IRegionViewRegistry regionViewRegistry)

        {

            this.container = container;

            this.regionViewRegistry = regionViewRegistry;

        }

     

        public void Initialize()

        {

            RegisterViewAndServices();

     

            // EmployeeModule - Views folder

            regionViewRegistry.RegisterViewWithRegion("MainRegion",

                () => container.Resolve<EmployeeMainPresenter>().View);

     

            regionViewRegistry.RegisterViewWithRegion("frmCaption",

                () => container.Resolve<frmCaptionPresenter>().View);

     

            regionViewRegistry.RegisterViewWithRegion("frmEmployeeList",

                () => container.Resolve<EmployeeListPresenter>().View);

     

            regionViewRegistry.RegisterViewWithRegion("TabInformation",

                () => container.Resolve<EmployeeInformationPresenter>().View);

     

            regionViewRegistry.RegisterViewWithRegion("TabAssigned",

               () => container.Resolve<EmployeeAssignedPresenter>().View);

     

            regionViewRegistry.RegisterViewWithRegion("TabInWork",

               () => container.Resolve<EmployeeInWorkPresenter>().View);

     

            regionViewRegistry.RegisterViewWithRegion("frmStatus",

                () => container.Resolve<frmStatusPresenter>().View);

     

        }

     

        private void RegisterViewAndServices()

        {

            container.RegisterType<IEmployeeMainView, EmployeeMainView>()

     

                // Layers

                .RegisterType<IEmployeeProviderBLL,EmployeeProviderBLL>()

                .RegisterType<IEmployeeProviderDAL,EmployeeProviderDAL>()

     

                // Views

                .RegisterType<IfrmStatusView, frmStatusView>()

                .RegisterType<IfrmCaptionView, frmCaptionView>()

                .RegisterType<IEmployeeListView, EmployeeListView>()

                .RegisterType<IEmployeeListView, EmployeeListView>()

                .RegisterType<IEmployeeInWorkView, EmployeeInWorkView>()

                .RegisterType<IEmployeeAssignedView, EmployeeAssignedView>()

                .RegisterType<IEmployeeInformationView, EmployeeInformationView>()

     

                // Services

                .RegisterType<IEmployeeService, EmployeeService>()

     

                // Models

                .RegisterType<IEmployeePresentationModel, EmployeePresentationModel>(

                                new ContainerControlledLifetimeManager());

        }

    }

    }


    It did some pretty heavy lifting which tells me everything that will be executed during Silverlight runtime - works. 

    The following is the Presenter, which is responsible for updating the Presentation Model (which the view is observing).  You can see that my Desktop Unit Test effectively exercises many, if not all, logic within the process.  

     

    Note: Silverlight unit testing is done in a browser...  I'd rather take this approach.

    Hope this helps in your quest to finding an architecture that works for you!

    Bill


     

    public class EmployeeListPresenter : PresenterBase<IEmployeeListView>

    {

        readonly IEmployeeService employeeService;

        readonly IEventAggregator aggregator;

        readonly IEmployeePresentationModel model;

     

        /// <summary>

        /// Constructor : setup class

        /// </summary>

        /// <param name="container"></param>

        /// <param name="view"></param>

        public EmployeeListPresenter(

            IEmployeeListView view,

            IEmployeePresentationModel model,

            IUnityContainer container,

            IEventAggregator aggregator,

            IEmployeeService service) : base(view,model,container)

        {

            this.aggregator = aggregator;

            this.employeeService = service;

            this.model = model;

     

            // Subscribe to ListBoxChanged event and

            aggregator.GetEvent<ListBoxChangedEvent>()
                      .Subscribe(ListBoxChangedEventHandler, true);

            aggregator.GetEvent<EmployeeEvent>()
                      .Subscribe(EmployeeEventHandler, true);

     

            // Async call to service to populate employee list. 
            // The EmployeeListEventHandler
    will be called when
            // data is received

            employeeService.GetEmployeeList();

        }

     

        /// <summary>

        /// Subscribed to in constructor - updates the model's
        /// SelectedEmployee property every
    time a new employee is selected

        /// </summary>

        /// <param name="args"></param>

        private void ListBoxChangedEventHandler(SelectionChangedEventArgs args)

        {

            model.SelectedEmployee = args.AddedItems[0] as Employee_Data;

     

            StatusBarEvent sbEvent = aggregator.GetEvent<StatusBarEvent>();

            if (sbEvent != null)

                aggregator.GetEvent<StatusBarEvent>().Publish(

                    new StatusBarData

                    {

                        Message = string.Format("You clicked {0}",
                                        model.SelectedEmployee.DisplayValue),

                        Panel = StatusPanel.Left

                    });

        }

     

        /// <summary>

        /// Handler for when Employee list is returned by service call to

        /// GetEmployeeList()

        /// </summary>

        /// <param name="args"></param>

        private void EmployeeEventHandler(EmployeeEventArgs args)

        {

            model.EmployeeList = args.EmployeeList;

        }

     }


    Tags: , ,
    Categories: CompositeWPF | SDMS


    Actions: E-mail | Permalink |  Grammar/Typo/Better way? Please let me know

    Enterprise Library 4.1 - unit test don't work

    Note: Run the "Install Instrumentation" menu option from the Microsoft Patterns and Practices menu or the Unit Test will fail during [TestInitialize] method. 

    When first attempting to run Unit Test for Enterprise Library 4.1, I was greeted with the following message (other times it would just hang - VS would go Not Responding): 

    Although I have an x64, Intel Core 2 Duo CPU T5750 @ 2.00Ghz system with 4 Gig RAM I also recognized a large number of Unit Test in the solution so I unloaded the following projects

    Keeping only the projects I'm currently interested in loaded (reflected by curved arrow above).

    Now my Unit Test would actually run but I was greeted with an odd (unexpected) error:

    What was odd about this error message was that the current assembly shows "Logging" and the error message complains that it can't load "Logging"; odd that it was complaining that it couldn't load itself.

    The key to this error was the PublickeyToken - the current running assembly (project) shows a PublicKeyToken=null where the error has an actual token.  Something was attempting to load a different assembly of the same name but from a .DLL (not project).  

    The next step was to locate the offending process - in this case it was the reader that was complaining so as I examined it's value I noted the "RollingFlatFileTraceListenerData".   Running a global search for this class (more specifically - within a .Config file) resulted in the following:

    The configuration file was requesting a specific .DLL where our Unit Test has a reference to the actual project - two different .DLLs.

    The fix was to remove everything after the Assembly name as shown below - this will allow it to default to the project being used by the Unit Test.

    Be sure to rebuild your solution before attempting to run the Unit Test after updating the .Config file.

    After complying with the above steps I was able to run the above referenced Unit Test and it passed. 

    VALIDATION SOLUTION

    Do a solution search and replace for the for the following (without the quotes):
    ", Version=4.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"

    After the above search and replace you'll find that we're down to 37 failures; many associated with the Performance Counter.

     To be continued...

    OTHER CONSIDERATIONS - Proper Setup

    Note: I use Visual Studio 2008 Professional Edition


    Tags: , ,
    Categories: Enterprise Library


    Actions: E-mail | Permalink |  Grammar/Typo/Better way? Please let me know