Google Analytics

Thursday, February 23, 2012

Prism Module Loading "Incorrect Format"

We ran across this this morning where a colleague was trying to load a module she had built from a DirectoryModuleCatalog into the shell of our Prism application. She was getting an error that the module could not be loaded, an error which included "An attempt was made to load a program with an incorrect format." We stripped the module down to the bare bones, but still were getting the error. In fact, when we tried debugging, the debugger never even got into the constructor of the module. 


A little research suggested that maybe the Unity dlls being referenced were different, which wouldn't surprise me since VisualStudio seems to go out and add whatever dll might be registered that it thinks fits the bill when you load up a project that another developer had started. After checking and re-checking the references for both the shell and module projects, we determined that probably wasn't it.


Then I found a bit about the build configuration. Her plugin was being built with an X86 target platform and the shell was being built for 'Any CPU' on her x64 machine. Voila. She went into Properties > Build for the Module project and changed the target to x64 (interestingly Any CPU was not available, which is maybe another issue), and the module loads into the shell as expected.

Friday, February 10, 2012

A Letter to Colorado Rep. Laura Bradford


Jan. 31, 2012

Ms. Bradford,


I made the mistake of getting into my car and driving back home to Brighton after enjoying a Rockies game and some beers downtown back in June. It was very irresponsible of me and I am very ashamed for having done it. I was pulled over by Brighton Police less than two miles from home and subsequently was arrested and convicted of a DUI.

I have done everything I have been ordered and advised to do and have finished most of those things early. I have completed 48 hours community service, paid thousands of dollars in fines and fees,attended a MADD victim's panel, done random breathalyzers 3 times per week, completed 24 hours of mandatory alcohol education and another 40 hours of alcohol therapy with another 12 hours left to complete. I went without being able to drive for 30 days mandated by the DMV, about another 30 days because they couldn't find the correct paperwork from my insurance company, and must go the next 2 years with an ignition Interlock system in my vehicle. Not only do I get to face scorn of those around me every time I start my car, but I also cannot travel for work since I cannot rent a car, putting my job in some jeopardy.

It was my first offense.

I impart this to you because you will not have the opportunity to gain the full extent of the implications of driving while intoxicated that my family and I have had the privilege of learning. Luckily I did not have to learn of the more sever consequences that some good people I have had the privilege of meeting have endured - causing damage and going to jail, or even worse hurting or killing another person. So far I have spent at least $3370 on DUI expenses, not including loss of work and vacation time to make scheduled hearings and probation appointments and other unrecorded expenses I paid with cash. The Interlock system is about $70/month and I will have 3 more months of alcohol therapy plus breathalyzers which will add at least another $1500 to that total. It just cash terms the DUI will easily cost me $5000. For that money I could have taken a helicopter home that unfortunate night.

With your position you do not have to deal with that. I am sure the bad press you are getting now is awful. Frankly, I'm sure that most of it is hypocritical coming from many people who have taken drinks and then driven home. As so many of my friends have told me, "That could have been me." But in a few months your bad press will be gone, and me and those without legislative privilege will still be blowing in straws to start our cars. However, with that position you have, you also have a lot of power to take Senator White's full advice and make positive change. Perhaps you will consider donating a portion of that $5000 or so you would have incurred to MADD. I know when I attended the impact panel they could have used more than the $5 I was able to donate. Perhaps you will consider attending an impact panel in your area? I wouldn't expect you to attend the education or therapy sessions that your legislative peers have mandated for anyone who gets caught with alcohol in their systems and isn't in the state legislature, but perhaps you will pick up the materials that every attendee is required to buy?

A few other things that I learned from this experience: Alcohol stays in your system much longer than they say. Your body doesn't process a drink an hour: It's more like a drink every two hours. Carrying a breathalyzer in your car will probably keep you out of more trouble than carrying a gun in your car will get you into. You can purchase breathalyzers on Amazon for around $150. Finally, it's not worth it to EVER get behind the wheel after drinking, even after one drink.

I hope you do not resign from your office, but instead use it to make some positive change in regards to drinking and driving. One thing that personally really bothers me is that a bar patron in Denver cannot hail a cab from the curb, but instead has to make a call or find a designated cab stand. I think more people drink and drive because of this. I've found that the other people I am in classes with generally are all good people who have made a very stupid mistake. There are very harsh consequences of getting caught with that in Colorado. You are really pretty fortunate that you don't have to deal with most of them.

Sincerely,

Benjamin Rice
Brighton, CO

Thursday, December 15, 2011

I am adding the module now to the shell. I'm looking at the UI Composition QuickStart in the guidance to get an idea of how to start. I want to have a main region and within that a tab region that I can add a tab to. Started by adding TabControl and TabItem template to the shell. Had to work out the fact that I didn't need the Silverlight adapter and other related markup. Added the module project as a simple class library and added the Views directory to it. Added the UserManagementModule class as a normal class. It implements IModule and its constructor takes a UnityContainer and RegionManager interfaces. In the Initialize() method we Register the UserManagement view with the tabRegion on the shell. So... we need to add the UserManagement View. We add that to the Views directory as a UserControl. I also just added a textBlock in the view to indicate that it is loaded. I had to explicitly override ConfigureModuleCatalog in the Bootstrapper and add the UserManagementModule to the catalog for now. Like I said before, I want to use the directory discovery method to get the modules, but we are taking baby steps here. So when I run this now an odd thing happens: I get a shell with two tabs. The first has no content. I think that it has to do with the fact that I am doing view injection rather than the view discovery of the QuickStart for the main region and I am getting the two methods crossed. The second tab has my content. It doesn't have the name on the tab, which is supposed to be bound to the View's ViewName property. Took me a few minutes to realize that I need to put that in the ViewModel object for the view. (Duh! Isn't that how all this is supposed to work in the first place?) So Next I will be adding the ViewModel for the UserManagement view, adding the ViewName property of that, and seeing if it gets displayed in my tab. The UserManagementModel gets added as a plain class that implements INotifyPropertyChanged, so it has a PropertyChanged event. The model is injected in the constructor of the view. Then we set the dataContext of the view to the model. This is a change from the MVP architecture we have used in the past where an interface to the view was injected into the constructor of a presenter and the view basically had no knowledge of its presenter. With MVVM the view will actively subscribe to events from the model and bind to its collections and commands. I'm wondering at this point if I should create an interface for the ViewModel, but I don't see why at the moment so leaving as is. WPF TabControl done differently than the Silverlight example in QuickStart, and that is what was giving me the two tabs and not correctly showing the view name on the tab as I wanted. I had to bind to Content.DataContext.ViewName rather than just ViewName as described in the QuickStart or DataContext.ViewName as some examples on the internets showed. Now I need to activate the tab. Hook up some dataService and bind users to a listControl. Add a second tab and probably localize region names.

Wednesday, December 14, 2011

Prism, WPF and My First Module

To start off with, I would like to create my shell, bootstrapper and first module. I'm choosing the User Management interface of our current project as that initial module, though to begin with all I plan on doing is loading a tab control into the main region. My current plan is to create a shell with a main menu and a main content region. One of the menu items will be Administration and one of the sub-menus under that will be User Management. When the user selects User Management the tab control with the title User Management should load in the main content region.

At first the menu content will just be static, but it would be nice if I could dynamically add the menu item at runtime. I'm not sure that I can specify that the User Management module should load OnDemand rather than OnStartup and still be able to populate the menu. That is one of the things to figure out. I am going to try using populating the module catalog with directory discovery. Another option I think we COULD possibly use is a ConfigurationModuleCatalog. In either case we just need to make sure we are doing thigns securely so that no one can drop in a rogue assembly that could be discovered and loaded. Also I would like to be able to "unload" the tab control and not just hide it so that the control is not using overhead memory. That is another thing to experiment with.

Then the user management view is probably going to be composed of two related views: a Roles control and a Users control. Each of those controls will have a list of their respective model data as well as a Detail view for selected items. So my next task will be to wire up the model to correctly display the system's roles and users as well as the command(s) for selecting an oject from the list and showing its properties in the details view.

In the Users control there will be commands for adding, editing and disabling users. (There is no deleting of created users.) This will give me a chance to do error handling and business rules regarding the users (like password strength and that the default Admin user cannot be disabled).

For each of the controls there are a couple view-related features like the refresh and filter commands. They may be interesting to experiment with in the MVVM framework, but aren't terribly important.

Finally, there is the relatively simple task of adding and removing users from roles, which will give me the opportunity to see how my two controls will communicate with each other.

So on to creating my application and creating the shell and bootstrapper.

Following the walk-throughs for Prism Guidance:

In Visual Studio 2010: New Project > Windows > WPF Application. I'm naming it AdjudicationPoC.

Change MainWindow.xaml to Shell.xaml. VS changes the code-behind name to Shell.xaml.cs, but need to change the actual class name and constructor and also go into App.xaml and remove the startupURI attribute. The Bootstrapper will handle what starts, and in fact we can just go in now to the App.xaml.cs code-behind and override the OnStartup method to create and run our Bootstrapper. Of course, now VS is going to bitch that we don't have a Bootstrapper class so let's add that to the project now too.

Now I'm going to make the executive decision to use Unity as our IoC container, so our Bootstrapper is going to inherit from UnityBootstrapper, and to do this we need to include the Microsoft Prism Libraries. Again following the walk-through in the Guidance I created a Libraries folder in my solution folder. I copied in the Prism libraries (I'm just leaving out the MEF libraries, since, at least for now, I won't be using them), and added the references to my project. Our development team usually keeps our 3rd party libraries outside the solution, so that will probably change, but good for now.

After adding those references I just need to override the CreateShell and InitializeShell methodsof the UnityBootstrapper to create an instance of the Shell, set it as the MainWindow of our App and show it. I'm sort of not crazy about the reference to the App here, since it would be nice to be able to unit test the bootstrapper (and, more importantly, automate that test) without it. It isn't doing much at the moment, plus I may see what MSTest can do for me in order to really test it. That's for tomorrow.
plus I may see what MSTest can do for me in order to really test it. That's for tomorrow.

Wednesday, December 7, 2011

Playing with Prism 4

We're at the end of this project I've been working on for some time now. As per usual, we kind of got into this fire drill situation of trying to get everything all wrapped up at the end. So things like trying to implement acceptance testing got pushed aside in favor of squashing all these bugs that popped up precisely because we didn't implement acceptance testing in the first place. That is all for another series of blog posts altogether I think.

Anyway, also as per usual we got to the end of this project and came to the realization that the architecture of the project was deficient to begin with. I don't mean to say that this just dawned on us. I mean I think we knew before that the architecture was deficient. I mean "realization" in the sense that the problem "manifested" (perhaps a better word) itself at the end. The core components of the application are a WPF client that interfaces with a web service as well as a windows service which handles data loading. The web service can interface with the windows service to report back to the client when loading occurs. Both services are WCF services, and we could probably improve on their architecture to an extent, but that was a bullet we bit about halfway through the project. At that time we made some significant changes to the service side, so while there are definitely some changes we could make, the architecture is ok.

On the client side though we ran into issues. The client-side architecture is a bastardization of one we used on a previous project. That project used the Composite Application Library and an MVP architecture. It was a big, complex application. We thought we could scale that down and cut out some things we wouldn't really need. It turned into sort of an ugly bastard child in every sense of the word.

So, after the fact (which is totally the way I LOVE to do things), I am looking at Prism 4, seeing how it improves I what we did with CAL and figuring out how we can use it for the second release of this project, which we'll probably start after the Holidays. So what follows in the next few episodes are my rambling thoughts as I experiment with Prism and WPF and reassembling pieces of the existing client into something that I don't want to throw out a window.

Wednesday, November 9, 2011

Integrating Fitnesse with CCNet

Just have to laugh because the CURRENT CruiseControl.Net documentation on integrating Fitnesse and CCNet says, "Use the TestRunner which comes as part of the standard fitnesse distribution to run all the fitnesse tests and generate the results. You will need to use the task," and dates from 2006. This is somewhat akin to teaching your grandmother how to send email by saying, "Use Outlook."

Anyway, I have a test running automatically with the build and passing. The problem is with my report. I want to have a link from the CCNet dashboard for the project build to a nice, neat fitnesse report. CCNet 1.6 has something in the packages called Fitnesse Results package, but there is, of course, no documentation on using it.

Monday, October 31, 2011

CruiseControl.Net, or Is There A Limit to my Patience?

Continuing with my trials and tribulations in regards to CCNet

Building my projects. I needed to update the svn settings file we have with the path to the svn executable. Then, we are using Rodemeyer.MsBuildToCCNet.dll for the MSBuild tasks and the server needed that library. So I had to copy that to the CCnet server directory.

I ended up just installing VisualStudio 2010 on the build server though I wanted to avoid it. We are using utilities like resgen.exe as well as our unit tests using MSTest. I'm aware I can jump through hoops to install these separate of VisualStudio, but it ended up being a lot easier to just install VS.

I am setting up CCNet to run an NCover task to run our unit tests in MSTest (Apparently I was on drugs when I was thinking earlier that our tests were done in NUnit; I'm sort of wishing now that we had stuck with NUnit rather than using MSTest). The path to MSTest is in it's regular place after installing VisualStudio: C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\MSTest.exe. NCover is at its default installation place: C:\Program Files (x86)\NCover\ncover.console.exe. Hopefully this is as simple as putting the NCover profiler task into my ccNet project definition (http://www.cruisecontrolnet.org/projects/ccnet/wiki/NCover_Profiler_Task).

<ncoverprofile>
<executable>C:\Program Files (x86)\NCover\NCover.Console.exe</executable>
<program>C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\MSTest.exe</program> <testproject>myproject.test.dll</testproject>
<workingdir>build\unittests</workingdir>
<includedassemblies>myproject.*.dll</includedassemblies>
</ncoverProfile>

Yeah... definitely not that easy. First off, the ncoverProfile tag has a bug and doesn't handle spaces in the paths. At least in the 3.3 version of NCover I was using to begin with. I got around that by using the DOS shortnames in the paths. CCNet just passes the testProject value as the first argument to MSTest, which also causes a problem. You get the error from MSTest: 'Invalid switch "c"'. The assembly name in the testProject node needs to have the /testcontainer switch appended. Then I had set the includedAssemblies to *.dll since I figured that would include all the dlls in my working directory. I got an error from NCover that the includedAssemblies included an invalid wildcard '*'. Really?!? Ok, so I just lef the includedAssemblies value blank figuring NCover would just be smart enough to include the dlls in the working directory, and it seems that maybe it was close anyway, because I finally got the MSTest command to at least run my unit tests. My task at this point looked like this:

<ncoverprofile>
<executable>C:\PROGRA~2\NCover\NCover.Console.exe</executable>
<program>C:\PROGRA~2\MICROS~2.0\Common7\IDE\MSTest.exe</program> <testproject>/testcontainer:MembershipTests.dll</testproject>
<workingdir>build\unittests</workingdir> <includedassemblies></includedassemblies>
</ncoverProfile>

MSTest was running but NCover was erroring saying that there was no coverage data: "NCover.Console is returning exit code #20000". Supposedly this can happen when you use NCover 64 bit to cover a 32 bit assembly or vice-versa. My assembly was built for AnyCPU, so I thought I should be ok. I tried running the tests through NCoverExplorer and was getting a similar error, so since only the 32-bit version of NCover was installed on this build machine (since that's the installer we had locally available before), I figured it wouldn't hurt to install the 64-bit version and see if that was indeed the problem.

Once I have the 64-bit version installed, my tests ran fine through NCoverExplorer even though I was still referencing the 32-bit installation of NCover on the machine! So, I was like... ok, let's try this out through CCNet now. After working through an issue with an old NCover task being in the MSBuild project (It suddenly reared its head since it HAD been looking for NCover in C:/Program Files/NCover instead of C:/Program Files (x86)/NCover and was simply failing to even load until I installed the 64-bit version on the new machine *sheepish*), I am getting 42 passing tests, 1 failure with 72% coverage. Not horrible considering it has been a while since we've gotten these tests to run at all. Just gotta go fix that one test, get my build to go green (it fails automatically on the failed unit test) and see if I can't get the coverage up at least to our 85% target. Then the more daunting task: to integrate this into the other VisualStudio projects that comprise the system. While the Membership providers were written in a TDD manner, most of the rest of the system was not. Last I looked, our unit test coverage was somewhere around 15%. Ugh. Finally our real goal here is to get some decent coverage with our acceptance testing. I still have to get Fitnesse running with CCNet on the new machine.

I frankly am wondering what sort of testing ThoughtWorks does before releasing some of their updates. I have to guess they aren't doing much testing on a Windows environment with Microsoft tools. I have to agree that it seems more and more that CCNet and MSBuild with MSTest simply don't mix well and that, though I have gotten this far, Continuous Integration shouldn't be this hard.