Thoughts from Dan Miser RSS 2.0
 Friday, February 01, 2008

I would like to take it upon myself to announce the formation of the Milwaukee chapter of the ALT.NET UserGroup. It will meet the first Wednesday of every month, with the first meeting to take place on 3/5/08 @ 7pm at 10000 Innovation Drive, Milwaukee, WI. Pizza and drinks will be served, and the event will be free to attend. Thanks to SpiderLogic for sponsoring the first meeting.

This group will cover agile development tools and techniques with .NET, best practices for architecture and coding, emerging technologies, and anything else the group decides to cover. For more backstory on ALT.NET, read this post. The use group will be a very participant-driven group. I will not look to lead this group in any significant way, other than to call this group to order, and get people involved in sustaining it. I've learned from other user groups that if a group is too dependent upon one person, it is a matter of time before it fails.

For the first meeting's agenda, I propose we get some volunteers to take on some minimum responsibilities and then break into an OpenSpaces format, where technical topics will be presented by anyone who wants to present. I don't want this to be yet another 1-way presentation medium for 1-2 hour topics, so be prepared to be engaged, discuss, and share (bring your laptop to showcase code and/or slides). I'll take a swipe at talking about ASP.NET MVC this first meeting. If you have something you want to see covered, or especially if you want to cover something, post a comment, and we'll get it on the agenda.

Please pass this notice around to anyone you think will be interested! If you plan on attending, I would appreciate either a comment on this blog or email to dmiser@distribucon.com, just so we can gauge how much food and drink to have on hand. I am really excited about this, and look forward to seeing everyone there!!

Friday, February 01, 2008 3:46:14 PM (Central Standard Time, UTC-06:00)  #    Comments [4] -
.NET | ALT.NET
 Tuesday, January 29, 2008

I have a .NET application that generates an XML file via serialization (through XmlTextWriter) and submits the data via https. Recently, they changed something on their end to only accept an upper cased UTF-8 encoding, like this:


<?xml version="1.0" encoding="UTF-8"?>

Unfortunately, using the .NET classes mentioned above, it generates the encoding string in lower case. I could find one mention of this on google, and they said to have the other company change (not an option here), or override XmlTextWriter. I went with that approach, making heavy use of Reflector along the way. I started by looking at the WriteStartDocument method, but realized that the private StartDocument is the thing that generates the output. It also gets called by the overloaded WriteStartDocument, so I'd need to override that method, too. However, in the private StartDocument method, it uses a bunch of private variables and generates output via another private method, InternalWriteProcessingInstructions. Ugly. At this point I realize that XmlTextWriter is not a class made for inheriting.

Back to Reflector, and I notice that the Encoding.WebName is the property used to write out the encoding string. I now create a descendant class of UTF8Encoding. The class is listed below. Now I just call XmlTextWriter, passing in UpperCaseUTF8Encoding.UpperCaseUTF8 for the Encoding type, and everything works perfectly.

    public class UpperCaseUTF8Encoding : UTF8Encoding
    {
        public override string WebName
        {
            get { return base.WebName.ToUpper(); }
        }

        public static UpperCaseUTF8Encoding UpperCaseUTF8
        {
            get
            {
                if (upperCaseUtf8Encoding == null)
                    upperCaseUtf8Encoding = new UpperCaseUTF8Encoding();
                return upperCaseUtf8Encoding;
            }
        }

        private static UpperCaseUTF8Encoding upperCaseUtf8Encoding = null;
    }
 Friday, January 25, 2008

I went in search of an application that would synchronize my bookmarks. It needed to meet the following minimum specifications:

  • Sync between Windows and Macintosh
  • Sync bookmarks between IE, Mozilla, and Safari
  • Sync between machines
  • Automatic synchronization. If I have to perform a manual step, I'm not interested.
  • Could not be an Internet-only bookmark storage service
  • Good conflict detection and resolution

Sync2It met all of those requirements, and after using it for a couple of weeks with no real major issues, I bought it. Diigo and Google bookmarks were very good applications, too, but didn't pass some portion of my needs. I did email the author about some enhancements I'd like to see to make Sync2It even better. I'd encourage you to try and buy Sync2It. That way, maybe these suggestions have a chance of getting implemented. :-)

  • While the Mac download doesn't say it, it does appear to work with Leopard.
  • The Mac version only syncs with IE and Safari. We need Mozilla support on this platform.
  • Provide an easy way to auto-launch the Sync2It application as a daemon when logging in.
  • We need to be certain that Safari 3 is supported (both on Mac and Windows).
  • It would be nice to have some kind of log to see the actual activity of a given sync.

Here's hoping this will let me focus on saving and categorizing bookmarks, as opposed to constantly leaving stray bookmarks around and needing that one bookmark on the one machine I'm not currently using!

Friday, January 25, 2008 3:43:44 PM (Central Standard Time, UTC-06:00)  #    Comments [1] -

 Thursday, January 24, 2008

I had a need to move some VB.NET code to C# today. We're still not at the point where we can just mix and match languages within an assembly, and in this case, it would be more work than I wanted to separate things out. I looked around the net, and the best code converter that I found (read: it successfully converted everything I threw at it, where others failed) was this one.

Thursday, January 24, 2008 9:36:42 AM (Central Standard Time, UTC-06:00)  #    Comments [3] -
.NET
 Wednesday, January 23, 2008

I needed to put 2 test assemblies into my automated CruiseControl.NET build and get coverage results. It appears that this is a pretty common need, with some tricks to get things working properly. According to http://www.kiwidude.com/blog/2006/10/ncoverexplorer-merging-ncover-reports.html, you need to either use an NUnit project file to contain all of the unit tests or merge the coverage xml files in the NCoverExplorer task.

NUnit project setup and problems

By using an NUnit project file, all of the tests are executed within one call, which produces one coverage.xml file. This allows tests from multiple test assemblies to be merged together into one coverage file that NCoverExplorer will understand automatically.

<TestAssemblies Include="MyApp.Tests.nunit" />

MyApp.Tests.nunit contents:

<NUnitProject>
  <Config name="Default" binpathtype="Auto">
    <assembly path="MyApp.DAL.Test\bin\Debug\MyApp.DAL.Test.dll" />
    <assembly path="MyApp.Service.Test\bin\Debug\MyApp.Service.Test.dll" />
  </Config>
</NUnitProject> 

The major downside of this approach is that, according to http://nunit.com/blogs/?p=9,  when using the NUnit project file, the config file that gets loaded needs to be based off of the NUnit project filename (i.e. in this case, MyAppT.Tests.config) and not the individual test assembly filenames. This means that we need to continually merge all of the app.config files into one "master" config file. This is not exactly a long-term, maintainable solution.

NCoverExplorer task setup

That brings us to the second possible solution presented above, namely to merge multiple coverage files together. To do this, you need to take some care in how you set the properties up for the tasks so that you don't overwrite coverage output files. My current build project looks similar to the one below. One other thing to keep in mind is to include the *.CoverageMerge.xml file in your CC.NET config file's <merge> section for this project.

<ItemGroup>
  <TestAssemblies Include="$(DALTestAssembly)" />
  <TestAssemblies Include="$(ServiceTestAssembly)" /> 
  <NCoverAssemblies Include="$(DALAssembly)" />
  <NCoverAssemblies Include="$(ServiceAssembly)" />
  <NCoverCoverageFiles Include="**.Coverage.xml" />
</ItemGroup>

<Target Name="Test" DependsOnTargets="CoreBuild">
  <NCover ToolPath="lib\NCover\"
    CommandLineArgs="%(TestAssemblies.FullPath) /xml=%(TestAssemblies.Filename).xml /labels /nologo"
    CommandLineExe="lib\NUnit\nunit-console.exe"
    CoverageFile="%(TestAssemblies.Filename).Coverage.xml"     
    LogFile="%(TestAssemblies.Filename).Coverage.log"
    LogLevel="Verbose"
    WorkingDirectory="$(MSBuildProjectDirectory)"
    Assemblies="@(NCoverAssemblies)"
  />

  <NCoverExplorer
    ProjectName="MyApp"
    ReportType="ModuleClassSummary"
    OutputDir="$(MSBuildProjectDirectory)"
    XmlReportName="MyApp.CoverageSummary.xml"
    HtmlReportName="MyApp.CoverageSummary.html"
    ShowExcluded="True"
    SatisfactoryCoverage="80"
    CoverageFiles="@(NCoverCoverageFiles)"
    MergeFileName="MyApp.CoverageMerge.xml"
    ToolPath="lib\NCover\Explorer"
  />
</Target>
Wednesday, January 23, 2008 9:44:21 AM (Central Standard Time, UTC-06:00)  #    Comments [0] -

 Friday, January 11, 2008

To be sure, this is an incomplete list, but it is a good start. Here's what I don't like about LINQ to SQL:

  • It only works with MSSQL. Yes, this point has been beaten to death, but it is entirely justified. Third party solutions don't cut it. LINQ to SQL intentionally seeks to exclude a sizeable population because of this hair-brained decision.
  • No way to easily specify adhoc LINQ queries. This doesn't count. I know the benefits of design-time queries, but I should also be allowed to shoot myself to get the added flexibility if I so choose. Building up expression trees is not a viable option for every day development.
  • The constant labeling of LINQ to SQL as an OR/M. That label considerably overstates what this technology does. One to one mapping between a table and a class is not really OR/M. It seems like they want to force you to change your database by writing stored procs and views to make your object model better.
  • There is no automated way to easily pick up changes to the database schema.
  • There is no easy way to preserve changes to the generated code. e.g. I change the name of the automatically generated class from collection_details to CollectionDetails, but I evolve the schema of the table. When I re-add the table, I need to set all of the custom properties again. I know I shouldn't change generated code, but see the next point.
  • Speaking of collection_details, it would be much better if the underlying class generator had some options to clean up legacy table names (e.g. remove underscores, camel case resulting table and column names).
  • No many-to-many support. In short, when you have an junction table (aka associative table or cross-reference table), you will need to write code like this: User.UserPermissions[0].Permission vs. User.Permissions[0]. Until we see LINQ to Entity (if ever), we do have this, but you can't use the new entity in a LINQ query.
  • There is no built-in solution to using LINQ across tiers. I don't want to expose my LINQ classes (see the point above about the tight coupling between database and objects) as I may want to change my database, and I don't want that cascading to all of the places that use it. There is also no diffgram, so even if I did it, I would have to write my own change tracking and resolving support. I went to an OpenSpaces meeting on this very topic during CodeMash, and the consensus was not flattering.

In short, it seems like this part of LINQ was released way before it was ready. But it does demo well...

Feel free to add your own grievance to the comments.

Friday, January 11, 2008 12:23:26 PM (Central Standard Time, UTC-06:00)  #    Comments [5] -
.NET | LINQ
 Tuesday, January 08, 2008

I have a PATH that is miles long, and I needed to find out where a certain application was launching from. On a good operating system, this kind of functionality is built in. :-) On a Windows operating system, you can create a BAT file, or download a utility.

Tuesday, January 08, 2008 3:42:36 PM (Central Standard Time, UTC-06:00)  #    Comments [6] -

 Sunday, December 30, 2007

I have been reading Dustin Campbell's series, The 12 Days of Refactor! X-mas, with interest. He's a very good writer, and has broken down a bunch of Developer Express features into easy to digest chunks of information.

The episode I linked to above touched on the XML Literal support that shipped with VB in Visual Studio 2008. The one sentence summary of this technology is that it lets the VB compiler translate raw XML in the source code into strongly-typed code using XML classes under the hood. It's a very nice idea, and I encourage you to look at the links to learn a little more about it.

While the VB team thought this was a good idea and added the feature, Anders and the C# team believed that it was superfluous to add such a thing to the C# side. I haven't really made up my mind which group I side with yet. However, Anders is benevolent :-), so he gave us the little-documented PasteXmlAsLinq addin that will take XML on the clipboard and paste it into a file in C# syntax building the XML up using classes like XElement.

In a default install of VS2008, open C:\Program Files\Microsoft Visual Studio 9.0\Samples\1033\CSharpSamples.zip and extract the LinqSamples\PasteXmlAsLinq files. There is a Readme.html file in there that tells you how to build, install and use the addin.

While this isn't the same as VB's support for XML Literals, it does make things easier to work with.

Sunday, December 30, 2007 5:02:25 PM (Central Standard Time, UTC-06:00)  #    Comments [1] -
.NET | LINQ | XML
Navigation
Archive
<February 2008>
SunMonTueWedThuFriSat
272829303112
3456789
10111213141516
17181920212223
2425262728291
2345678
About the author/Disclaimer

Disclaimer
The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.

© Copyright 2010
Dan Miser
Sign In
Statistics
Total Posts: 339
This Year: 5
This Month: 0
This Week: 0
Comments: 618
All Content © 2010, Dan Miser
DasBlog theme 'Business' created by Christoph De Baene (delarou)