Tuesday, May 18, 2010

DataContext OnDelete partial method doesn't delete

When using the OnDelete or OnUpdate partial methods in the DataContext (to say, cascade deletes to a child object) you may find that the object itself doesn't get deleted.

This was surprising to me. The reasoning makes sense, though. These partial methods totally replace the regular delete processing. They aren't a "pre" or "post" delete; they are "instead of" delete.

To make the original object actually get deleted, you should call ExecuteDynamicDelete(instance).

As seen here.

Tuesday, May 04, 2010

Rhino Expectations should be hit but aren't

I was writing a unit test for a method implemented as a linq query returning IEnumerable and using RhinoMocks to stub out a dependency. Despite all my best debugging efforts where it appeared obvious that the expectations I set should have been met, VerifyAll was throwing with Expected #1 Actual #0.

After lots of head scratching I realized that it's because when calling VerifyAll, nothing had yet enumerated the result of the method call. Linq's laziness had prevented my code from running and therefore meeting my expectations.

After further head scratching, it turns out I've already hit the same problem once before and blogged about it here, so I'm just going to leave this up as a reminder to read your own blog.

Sunday, November 29, 2009

VSIX with the VS2010 Beta 2 SDK

I'm working on an extension for VS2010 that I'll definitely be talking more about in the future, but I wanted to start by discussing the difficulties involved in even getting started.

I'd heard a lot about how VS2010 was much easier to extend than previous versions, particularly due to the use of MEF for writing extensions. What I didn't take into account before coming up with my idea is that MEF is only used for extensions to the editor (which my idea doesn't involve). That's how I found myself writing a regular extension.

Optimizing the Editor extension experience seems to have influenced the available project templates as well. The Beta 2 SDK comes with project templates for Editor Viewport Adornment, Editor Margin, Editor Classifier, Editor this and that, WPF and Winforms controls, and then a default VSIX Project. You'd think, then, that the one most applicable to my extension would be the VSIX Project, but that thought was where the difficulty began.

I'm going to suggest up front that the best way to write a non-Editor extension is to find a sample that most closely matches what you want to do on the MSDN Code Gallery for VSX and just modify it instead of starting with the blank project like I did. The main issues seem to stem from the SDK providing UI to edit many of the involved files, but in a totally incomplete way leaving many of the necessary settings only discoverable via editing the files in the XML editor or something.

The first thing you'll find when comparing the VSIX Project to any of the samples is that the VSIX Project has a special project type that gets you another tab in project properties. While this tab does have a few useful options, it doesn't expose the settings necessary for making sure a PkgDef file gets generated and that it contains your assembly dll and pdb and that they all get deployed to the right place for the Experimental Instance of VS to find them for debugging. The way I got all this to work was to manually edit my csproj file and change the following elements from "false" to "true".


<GeneratePkgDefFile>true</GeneratePkgDefFile>
<IncludeAssemblyInVSIXContainer>true</IncludeAssemblyInVSIXContainer>
<IncludeDebugSymbolsInVSIXContainer>true</IncludeDebugSymbolsInVSIXContainer>
<IncludeDebugSymbolsInLocalVSIXDeployment>true</IncludeDebugSymbolsInLocalVSIXDeployment>
<CopyBuildOutputToOutputDirectory>true</CopyBuildOutputToOutputDirectory>
<CopyOutputSymbolsToOutputDirectory>true</CopyOutputSymbolsToOutputDirectory>


In order to make sure your package actually gets registered with the Experimental Instance and that the dlls are referenced out of the local folder instead of the GAC you have to add this PropertyGroup section to your csproj as well


<PropertyGroup>
<RegisterOutputPackage>true</RegisterOutputPackage>
<RegisterWithCodebase>true</RegisterWithCodebase>
</PropertyGroup>


The next thing you'll notice is that the samples all have .vsct files in them that define all the Menus, Groups, Buttons, Bitmaps, etc. These files basically control how your extension is integrated with Visual Studio. Since your project doesn't have this, you'll have to add it. Unfortunately there isn't an item template for this, so the closest match is just an XML file. Of course it can't be that easy. There's actually a compilation step that happens against this file, too (it isn't just data). No problem, let's just change the Build Action to the same thing the sample has. Wait, why isn't it in the dropdown? Time to open the csproj file manually again and look for your newly added vsct project. In the ItemGroup, instead of a Content or None element, you want a VSCTCompile element that looks like this:


<VSCTCompile Include="Filename.vsct">
<ResourceName>1000</ResourceName>
</VSCTCompile>


That magic number in the ResourceName element must match up with the value you put in the ProvideMenuResourceAttribute you put on your package.

Now the VSCT is set, the project is configured properly, and everything works, right? Not yet. If you compile now, you'll get a weird error in the VS SDK targets file like "No resource file set the resource merger". I guessed that this meant we needed a resource file so I added one. That didn't quite fix it so I had to go back into the csproj and change how the resource file was listed there. Underneath the EmbeddedResource element, add an element called "MergeWithCTO" with the text "true" and that problem should go away.

Ok now everything should run, the breakpoints set in the package will be hit and the real work can begin. See why I suggested starting with a sample and just changing it?

I went ahead and created connect items for these: VSCT, Incomplete Properties UI, and Resource files.

Friday, November 20, 2009

Back from PDC

The PDC was fun (who doesn't like free laptops), but not as energizing as previous years. Many of the announcements were just refinements of things previously announced.

The new Silverlight 4 stuff looks promising, as do the new features in Entity Framework 4.0. I'm also interested in trying to pry the IQueryable serialization stuff out of RIA so I can make use of it in a more typical distributed system situation. RIA is explicitly designed to try and hide the distribution tier (which I understand for the scenarios they are targeting), but the data services stuff is too cool to leave it limited to that.

I had several good talks with different Microsoft folks about EF, MVC, and F# among other things. Now that all the session videos are online almost immediately, these in-person interactions are the main draw of the conference (well, that and the laptop).

Having the conference end later in the day Thursday was good, since it made me stay until Friday and gave us a chance to head to Santa Monica Thursday night and dip my toes in the ocean. We arrived right as the sun was setting and immediately forgot about all the stupid traffic on the way there.

Wednesday, August 19, 2009

Stepping into methods with yield return

I had a failing unit test (Rhino Expected Call wasn't happening) so I ran with the debugger to try and investigate. When I got to the method in question I tried to step into it but the debugger acted like I had pressed Step Over. The output window had something like this in it: "Step into: Stepping over method without symbols".

After some investigation I figured out the issue. The method in question was returning an IEnumerable and was implemented using "yield return". My test had code like:

var result = callTheMethodInQuestion();
repository.VerifyAll();

Can you see the issue yet?

I was never enumerating result, so the method in question was never actually running, which is why my expected call didn't happen. Slapping a .ToList() onto result triggered the method evaluation and everything worked fine.

Tuesday, June 30, 2009

AddFromTemplate has misleading documentation

When building a custom solution template, it's sometimes useful to programmatically execute other templates. In our case, we have a unit test project template that we'd like to call from the domain template. To do this, you use a method off of ENVDTE90.Solution3 called AddFromTemplate, which takes among other things, the path to the template, the output directory, and the new project name.

The documentation for this method says this about the project name parameter:
"The name of the project file in the destination directory. This should include the extension."

Seems pretty clear about whether or not to include the extension, right?

The first version of our wizard included the extension. Unfortunately, this resulted in the $safeprojectname$ parameter ending up with the extension in it as well. Since this parameter is also used to define the default namespace, we ended up with test classes whose full names were something like MyApplication.MyProjectTests.csproj.MyClassTests. Yuck.

The solution appears to be to completely disregard the documentation and don't include the extension. So far this appears to be working.

Wednesday, June 03, 2009

How to access a Virtual PC from the Host

Most of the documentation I've seen for Virtual PC describes how to setup the virtual machine itself to be able to access the network. I have an application server installed on a virtual, though, that I'd really like to be able to access from the host machine.

This took some digging to find, but this article was exceptionally helpful. The only extra step I had to take was to disable Windows Firewall on the virtual machine so it would let the network traffic through.