SDMS / VisioTool - Controller completed w/unit test - MAF

If like me, you were dismayed to learn that Visio for Architects was not supported in Visual Studio 2008  you'll appreciate this upcoming tool; particularly if you want to reverse engineer your code so that you can create your UML diagrams without having to manually input all the class information.  

Fortunately there is a workaround (I posted it HERE) which this utility performs.  Without it there was quite a bit of grunt work involved - enough for me to push architecture to the back-burner.   With a new requirement on the front burner I wasn't afforded this opportunity (to back-burner architecture).  There are to many components for me to wrap my mind around the solution, so I'll have to architect the existing WPF Calculator to prepare a gap analysis so that I can successfully create a Managed Add-in Framework (MAF) module loader for my CompositeWPF SDMS solution. 

For those that can't wait for the UI to be completed (like me) I completed the TDD of the controller - the process is fully functional.   The two test that actually perform the work are remarked out (not shown in the screenshot below) because I don't want to inadvertantly convert the solution; I have my Visio document and have to back burner this utility for now.

Note below that the logger trapped some warnings.  I created test for invalid files as well as non-existent files and the test passed as I attempted to crash the process. 

After manually running the "Controller_CanPrepareVS2008SolutionForArchitecture" test I was able to open up my solution in Visual Studio 2005 - note that there are two projects that did not open - at a glance it looks like the WPF related projects (I have some more research to do).  Since CALDemoApplication is on the "New" side of the gap analysis and the DemoApplication is mostly UI stuff I can worry about them later - what I needed was the main solution projects (which I have below).  Updated: unfortunately UI has a great deal of logic in it (more below).

With my Visio document in hand I manually ran the "Controller_CanRestoreFromArchitecture" unit test and was able to successfully reopen my solution in Visual Studio 2008, compile and run the application with no issues.

IMPORTANT NOTE:  when I was closing the Visual Studio 2005 solution (after creating the visio document) I responded "No" to save solution updates.

Note: I manually added the newly created DemoApplication.vsd document to my solution
 

Source code for above available at HERE - Change Set 23906.    App | VisioTool | VisioToolModule and VisioToolModule.Tests

This is somewhat off topic but very cool so I'll mention it - below is the LINQ code I use to get my project list out of a Visual Studio 2005 / 2008 solution:

I created the query using LINQPAD - more about this HERE

UPDATED:  I investigated the two projects that won't open.  It appears the .NET 3.5 WPF Projects have a totally different header - it follows:

<Project ToolsVersion="3.5"
             DefaultTargets="Build"
             xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

The return on investment for supporting this new format (any efforts to convert it) are not worth it; particularly since I simply have to continue good programming practices and patterns for it not to be a problem; XAML projects will contain only UI code and I'll have all the supporting logic in class libraries (an example for my SDMS application is in the following image).

This does however cause a problem for me with the WPF Calculator program that I am architecting for my gap analysis.  Most, if not all, of the wiring-up logic is sitting in the DemoApplication's CalculatorHost.xaml code behind file - not good...   This is not good for reverse engineering nor does it promise to offer any reusable components (chomping at the bit for MEF to be released).  So now I'm in refactoring mode - pulling all of the code out of code-behind and placing it in an external library.  It's a painfully slow process because I have to refactor, test everything (there are no unit test), check-in and move another component and start the cycle over again....  

The ROI for all this work is that the WPF Calculator is my POC (Proof of Concept); when I'm done refactoring to get the code out of the UI I can complete the Architecture work.  My goal is to keep refactoring the WPF Calculator until it is a CompositeWPF application with reusable components that I can use in my SDMS application.   The WPF Calculator UI will have less code than my SDMS UI does below so I have no issues with manually adding these objects to Visio: 

 


Tags: , ,
Categories: LINQ | MAF | SDMS | LINQPAD


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

LINQPAD - Must have for your toolkit!

Last week while I was creating the StatusBar XAML for the SDMS application I read in the WPF Unleased book that you could use the grid for specifying width percentages.   I typed in the code verbatim and for the life of me could not get my SDMS application to display my left status bar textblock 1/3 the size of the right status bar textblock; both were defaulting to auto (the size of the text).  I tried labels, textblocks, etc to no avail.  Since I was wasting a lot of time changing, compiling and running, I jumped into XAMLPad ( .NET 2.0 SDK - command prompt) and got the same behavior (as expected) - when I remarked out the StatusBar elements the Grid worked! The issue is with the statusbar and the great thing was XAMLPad showed immediate results.   But this blog isn't about XAMLPad - when I get the StatusBar figured out I plan on blogging it thoroughly then...

As I started TDD on my LINQ Query to pull all the project names out of solution file (why explained below) I found myself coding, break pointing, running, examining and doing the same over again (once again losing much time in the process).   The thought came to me "google LINQPAD"; to my surprise a program came up and it instantly became my best friend.  If the author's intent was to sell his book he succeeded because within 15 minutes of using the application I was clicking the link and purchasing it :) 

REQUIREMENT 

Architect the CLRAddin WPF Calculator so that I can perform a gap analysis to determine what will be required to update the CompositeWPF application to support a CLRAddin module loader (modules loaded in their own AppDomain).   There are to many components to wrap my brain around it so the Architecture phase is neccessary.  The problem is I can't reverse engineer the calculator application with Visio for Architects because I'm using Visual Studio 2008 (it isn't supported).  

VISION STATEMENT

Complete a Visio Tool that will convert the solution and projects to Visual Studio 2005 so that it can be reverse engineered (generate all the Visio objects required for architecture).  Architect the existing WPF Calculator program and perform a gap analysis to create a MAFModuleLoader application for the CompositeWPF.

SOLUTION

Note before I continue: after downloading the LINQPAD if you'll go to C# 3.0 in a Nutshell (bottom left pane) and select "Before You Start" and click Readme.First() it will create the data objects (top left pane in image below) that you can use to run the samples and demos against.

In my case I use the following LINQ query to pull the project names and paths from the solution file:

string filePath = @"D:\MAFCompositeWPF\WPF_Caclulator\WPF Caclulator\DemoApplication.sln";

var query =
    from line in File.ReadAllLines(filePath)
    .Where(data => data.Contains("Project("))
    let record = line.Split(',')
    select new
        {
            Name = record[0].Split('=')[1].Replace("\"",""),
            Path = record[1].Replace("\"",""),
            Guid = record[2]
        };
query.Dump();  // This is a LINQPad command


The above query works against the following data:

Microsoft Visual Studio Solution File, Format Version 10.00
# Visual Studio 2008
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DemoApplication", "DemoApplication\DemoApplication.csproj", "{73C60A32-09A2-45C2-8C8C-8FD2817BB087}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HostView", "HostView\HostView.csproj", "{D589DDD6-6C12-4924-8831-3F312BBEA53E}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Calculator.Contracts", "Calculator.Contracts\Calculator.Contracts.csproj", "{D3E90866-D7BA-4B2A-A192-99649C2734BD}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AddInView", "AddInView\AddInView.csproj", "{A4AA9D5C-28EA-4933-B750-E434B847B66F}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AddInSideAdapters", "AddInSideAdapters\AddInSideAdapters.csproj", "{C7311113-761B-43CF-A327-89C884698A1D}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HostSideAdapters", "HostSideAdapters\HostSideAdapters.csproj", "{16B44B99-FB0D-4C61-9780-FF3E863F9D64}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BasicArithmaticAddIn.cs", "BasicArithmaticAddIn.cs\BasicArithmaticAddIn.cs.csproj", "{9CF465E4-003E-451D-ACBD-526E66CBB17A}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BasicVisualAddIn", "BasicVisualAddIn\BasicVisualAddIn.csproj", "{71E0E79C-FFF8-441D-82D2-D50FDE809C14}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GraphCalc", "Graphing Calculator\GraphCalc.csproj", "{1241B377-8BA7-4AE1-B6CD-66766348B521}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BasicStackOperations", "BasicStackOperations\BasicStackOperations.csproj", "{E8144FE1-51E4-4DD9-9620-5B3EFF5625A7}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "CAL", "CAL", "{28F48224-E0D4-4E43-93C6-E98D3789732E}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Composite", "..\CAL\Composite\Composite.csproj", "{77138947-1D13-4E22-AEE0-5D0DD046CA34}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Composite.UnityExtensions", "..\CAL\Composite.UnityExtensions\Composite.UnityExtensions.csproj", "{17831F3B-6B82-4916-BD2B-2CE2071EA622}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Composite.Wpf", "..\CAL\Composite.Wpf\Composite.Wpf.csproj", "{F807062D-6FC9-4FF0-A9F5-5F94653EDC4D}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SharedDLL", "SharedDLL\SharedDLL.csproj", "{7968177C-7610-4941-AB18-71BF5E2EA69D}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CALDemoApplication", "CALDemoApplication\CALDemoApplication.csproj", "{6DE42D1B-BF16-48F1-8EEF-22AFE1446254}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CALDemoApplication.Infrastructure", "CALDemoApplication.Infrastructure\CALDemoApplication.Infrastructure.csproj", "{EB012DE4-816A-44A6-957C-1FED71EE1C31}"
EndProject
Global
 GlobalSection(TeamFoundationVersionControl) = preSolution
  SccNumberOfProjects = 11
  SccEnterpriseProvider = {4CA58AB2-18FA-4F8D-95D4-32DDF27D184C}
  SccTeamFoundationServer = https://tfs05.codeplex.com/
  SccLocalPath0 = .
  SccProjectUniqueName1 = AddInSideAdapters\\AddInSideAdapters.csproj
  SccProjectName1 = AddInSideAdapters
  SccLocalPath1 = AddInSideAdapters
  SccProjectUniqueName2 = AddInView\\AddInView.csproj
  SccProjectName2 = AddInView
  SccLocalPath2 = AddInView
  SccProjectUniqueName3 = BasicArithmaticAddIn.cs\\BasicArithmaticAddIn.cs.csproj
  SccProjectName3 = BasicArithmaticAddIn.cs
  SccLocalPath3 = BasicArithmaticAddIn.cs
  SccProjectUniqueName4 = BasicStackOperations\\BasicStackOperations.csproj
  SccProjectName4 = BasicStackOperations
  SccLocalPath4 = BasicStackOperations
  SccProjectUniqueName5 = BasicVisualAddIn\\BasicVisualAddIn.csproj
  SccProjectName5 = BasicVisualAddIn
  SccLocalPath5 = BasicVisualAddIn
  SccProjectUniqueName6 = Calculator.Contracts\\Calculator.Contracts.csproj
  SccProjectName6 = Calculator.Contracts
  SccLocalPath6 = Calculator.Contracts
  SccProjectUniqueName7 = DemoApplication\\DemoApplication.csproj
  SccProjectName7 = DemoApplication
  SccLocalPath7 = DemoApplication
  SccProjectUniqueName8 = Graphing\u0020Calculator\\GraphCalc.csproj
  SccProjectName8 = Graphing\u0020Calculator
  SccLocalPath8 = Graphing\u0020Calculator
  SccProjectUniqueName9 = HostSideAdapters\\HostSideAdapters.csproj
  SccProjectName9 = HostSideAdapters
  SccLocalPath9 = HostSideAdapters
  SccProjectUniqueName10 = HostView\\HostView.csproj
  SccProjectName10 = HostView
  SccLocalPath10 = HostView
 EndGlobalSection
 GlobalSection(SolutionConfigurationPlatforms) = preSolution
  Debug|Any CPU = Debug|Any CPU
  Release|Any CPU = Release|Any CPU
 EndGlobalSection
 GlobalSection(ProjectConfigurationPlatforms) = postSolution
  {73C60A32-09A2-45C2-8C8C-8FD2817BB087}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
  {73C60A32-09A2-45C2-8C8C-8FD2817BB087}.Debug|Any CPU.Build.0 = Debug|Any CPU
  {73C60A32-09A2-45C2-8C8C-8FD2817BB087}.Release|Any CPU.ActiveCfg = Release|Any CPU
  {73C60A32-09A2-45C2-8C8C-8FD2817BB087}.Release|Any CPU.Build.0 = Release|Any CPU
  {D589DDD6-6C12-4924-8831-3F312BBEA53E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
  {D589DDD6-6C12-4924-8831-3F312BBEA53E}.Debug|Any CPU.Build.0 = Debug|Any CPU
  {D589DDD6-6C12-4924-8831-3F312BBEA53E}.Release|Any CPU.ActiveCfg = Release|Any CPU
  {D589DDD6-6C12-4924-8831-3F312BBEA53E}.Release|Any CPU.Build.0 = Release|Any CPU
  {D3E90866-D7BA-4B2A-A192-99649C2734BD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
  {D3E90866-D7BA-4B2A-A192-99649C2734BD}.Debug|Any CPU.Build.0 = Debug|Any CPU
  {D3E90866-D7BA-4B2A-A192-99649C2734BD}.Release|Any CPU.ActiveCfg = Release|Any CPU
  {D3E90866-D7BA-4B2A-A192-99649C2734BD}.Release|Any CPU.Build.0 = Release|Any CPU
  {A4AA9D5C-28EA-4933-B750-E434B847B66F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
  {A4AA9D5C-28EA-4933-B750-E434B847B66F}.Debug|Any CPU.Build.0 = Debug|Any CPU
  {A4AA9D5C-28EA-4933-B750-E434B847B66F}.Release|Any CPU.ActiveCfg = Release|Any CPU
  {A4AA9D5C-28EA-4933-B750-E434B847B66F}.Release|Any CPU.Build.0 = Release|Any CPU
  {C7311113-761B-43CF-A327-89C884698A1D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
  {C7311113-761B-43CF-A327-89C884698A1D}.Debug|Any CPU.Build.0 = Debug|Any CPU
  {C7311113-761B-43CF-A327-89C884698A1D}.Release|Any CPU.ActiveCfg = Release|Any CPU
  {C7311113-761B-43CF-A327-89C884698A1D}.Release|Any CPU.Build.0 = Release|Any CPU
  {16B44B99-FB0D-4C61-9780-FF3E863F9D64}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
  {16B44B99-FB0D-4C61-9780-FF3E863F9D64}.Debug|Any CPU.Build.0 = Debug|Any CPU
  {16B44B99-FB0D-4C61-9780-FF3E863F9D64}.Release|Any CPU.ActiveCfg = Release|Any CPU
  {16B44B99-FB0D-4C61-9780-FF3E863F9D64}.Release|Any CPU.Build.0 = Release|Any CPU
  {9CF465E4-003E-451D-ACBD-526E66CBB17A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
  {9CF465E4-003E-451D-ACBD-526E66CBB17A}.Debug|Any CPU.Build.0 = Debug|Any CPU
  {9CF465E4-003E-451D-ACBD-526E66CBB17A}.Release|Any CPU.ActiveCfg = Release|Any CPU
  {9CF465E4-003E-451D-ACBD-526E66CBB17A}.Release|Any CPU.Build.0 = Release|Any CPU
  {71E0E79C-FFF8-441D-82D2-D50FDE809C14}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
  {71E0E79C-FFF8-441D-82D2-D50FDE809C14}.Debug|Any CPU.Build.0 = Debug|Any CPU
  {71E0E79C-FFF8-441D-82D2-D50FDE809C14}.Release|Any CPU.ActiveCfg = Release|Any CPU
  {71E0E79C-FFF8-441D-82D2-D50FDE809C14}.Release|Any CPU.Build.0 = Release|Any CPU
  {1241B377-8BA7-4AE1-B6CD-66766348B521}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
  {1241B377-8BA7-4AE1-B6CD-66766348B521}.Debug|Any CPU.Build.0 = Debug|Any CPU
  {1241B377-8BA7-4AE1-B6CD-66766348B521}.Release|Any CPU.ActiveCfg = Release|Any CPU
  {1241B377-8BA7-4AE1-B6CD-66766348B521}.Release|Any CPU.Build.0 = Release|Any CPU
  {E8144FE1-51E4-4DD9-9620-5B3EFF5625A7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
  {E8144FE1-51E4-4DD9-9620-5B3EFF5625A7}.Debug|Any CPU.Build.0 = Debug|Any CPU
  {E8144FE1-51E4-4DD9-9620-5B3EFF5625A7}.Release|Any CPU.ActiveCfg = Release|Any CPU
  {E8144FE1-51E4-4DD9-9620-5B3EFF5625A7}.Release|Any CPU.Build.0 = Release|Any CPU
  {77138947-1D13-4E22-AEE0-5D0DD046CA34}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
  {77138947-1D13-4E22-AEE0-5D0DD046CA34}.Debug|Any CPU.Build.0 = Debug|Any CPU
  {77138947-1D13-4E22-AEE0-5D0DD046CA34}.Release|Any CPU.ActiveCfg = Release|Any CPU
  {77138947-1D13-4E22-AEE0-5D0DD046CA34}.Release|Any CPU.Build.0 = Release|Any CPU
  {17831F3B-6B82-4916-BD2B-2CE2071EA622}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
  {17831F3B-6B82-4916-BD2B-2CE2071EA622}.Debug|Any CPU.Build.0 = Debug|Any CPU
  {17831F3B-6B82-4916-BD2B-2CE2071EA622}.Release|Any CPU.ActiveCfg = Release|Any CPU
  {17831F3B-6B82-4916-BD2B-2CE2071EA622}.Release|Any CPU.Build.0 = Release|Any CPU
  {F807062D-6FC9-4FF0-A9F5-5F94653EDC4D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
  {F807062D-6FC9-4FF0-A9F5-5F94653EDC4D}.Debug|Any CPU.Build.0 = Debug|Any CPU
  {F807062D-6FC9-4FF0-A9F5-5F94653EDC4D}.Release|Any CPU.ActiveCfg = Release|Any CPU
  {F807062D-6FC9-4FF0-A9F5-5F94653EDC4D}.Release|Any CPU.Build.0 = Release|Any CPU
  {7968177C-7610-4941-AB18-71BF5E2EA69D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
  {7968177C-7610-4941-AB18-71BF5E2EA69D}.Debug|Any CPU.Build.0 = Debug|Any CPU
  {7968177C-7610-4941-AB18-71BF5E2EA69D}.Release|Any CPU.ActiveCfg = Release|Any CPU
  {7968177C-7610-4941-AB18-71BF5E2EA69D}.Release|Any CPU.Build.0 = Release|Any CPU
  {6DE42D1B-BF16-48F1-8EEF-22AFE1446254}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
  {6DE42D1B-BF16-48F1-8EEF-22AFE1446254}.Debug|Any CPU.Build.0 = Debug|Any CPU
  {6DE42D1B-BF16-48F1-8EEF-22AFE1446254}.Release|Any CPU.ActiveCfg = Release|Any CPU
  {6DE42D1B-BF16-48F1-8EEF-22AFE1446254}.Release|Any CPU.Build.0 = Release|Any CPU
  {EB012DE4-816A-44A6-957C-1FED71EE1C31}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
  {EB012DE4-816A-44A6-957C-1FED71EE1C31}.Debug|Any CPU.Build.0 = Debug|Any CPU
  {EB012DE4-816A-44A6-957C-1FED71EE1C31}.Release|Any CPU.ActiveCfg = Release|Any CPU
  {EB012DE4-816A-44A6-957C-1FED71EE1C31}.Release|Any CPU.Build.0 = Release|Any CPU
 EndGlobalSection
 GlobalSection(SolutionProperties) = preSolution
  HideSolutionNode = FALSE
 EndGlobalSection
 GlobalSection(NestedProjects) = preSolution
  {77138947-1D13-4E22-AEE0-5D0DD046CA34} = {28F48224-E0D4-4E43-93C6-E98D3789732E}
  {17831F3B-6B82-4916-BD2B-2CE2071EA622} = {28F48224-E0D4-4E43-93C6-E98D3789732E}
  {F807062D-6FC9-4FF0-A9F5-5F94653EDC4D} = {28F48224-E0D4-4E43-93C6-E98D3789732E}
  {7968177C-7610-4941-AB18-71BF5E2EA69D} = {28F48224-E0D4-4E43-93C6-E98D3789732E}
 EndGlobalSection
EndGlobal 


To produce the following results (bottom pane holds the Dump() results):

I was able to tweak and tune my LINQ query (instantly seeing the results) until I had the output I was looking for.


Tags: , ,
Categories: LINQ | MAF | SDMS | LINQPAD


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