# Saturday, July 19, 2008

It's 1:30AM, I guess it's Saturday now. =)  I've been furiously pounding away for the past two weeks building a new for RADE 4.0.  Gotta love 12 - 18 hour days for two weeks (Good thing I love software development).  My wife is away for the week, so I can continue working these stupid hours for another week.  Anyhow I've chosen to proceed with for the time being.  with the looks really cool and I've used it for some small research/test projects recently, but with the lack of support for database other than SQL server - it's not an option at this time.

NHibernate was a tough curve for me.  Initially, I started testing code generators.  After spending a significant amount of time reading, testing, and pulling out hair I came to the conclusion that .  From my experiences is probably the best code generator out there right now - but its still lacking in some areas.  More importantly however, I learned that code generation is not a good place to start when implementing NHibernate for the first time.  There is so much going on under the hood - in my opinion you need to start off doing a reasonable size project by hand.  Code generation has significant benefits, because the generated code is so similar with simple replacements it just makes a lot of sense once you wrap your head around what's going on with NHibernate.

As per my when implementing nHibernate by hand, .  Just the other day I found a *great* ReSharper .  When editing NHibernate HBM XML files, it does a bunch of validation right in the editor.  Saves you a lot of time finding problems without having to actually run a unit test and debug sometimes cryptic error messages.

I bought a copy of NHibernate In Action.  I would recommend this book to you only if you have no experience, or understanding of Object Relational Mappers.  As the book stands right now, it's not really a good developer reference and only covers really basic examples.  The documents that helped me the most to get everything up and running was .  The NHibernate documentation is pretty cryptic.  Don't read this stuff 12 hours into your day.  No amount of RedBull will give you the focus needed to make sense of it.  In the first 8 hours of the day, its quite helpful.

I primarily work in VB.NET.  For this project however, I switched to C#.  Maybe now, the my colleagues at will stop giving me a hard time =).  Seriously though.  Examples are a LOT easier to come by in C#, probably 10:1.

Finally, get NUnit running.  I had a lot of problems using the built in Microsoft Test projects with NHibernate - so I'll be sticking with NUnit. If you've never done unit testing (you know who you are) do it.  Particularly in this case - its crucial.  You (Again you know who you are =]) used to write simple winform apps, and put a bunch of buttons on them.  Don't do that. 

So, if you are one of the RADE non-developer users and you read on this far.  Congrats.  This milestone will not directly help you with your use of RADE.  However, it's a large step forward for the underlying architecture - and you will benefit from that. 

Well back to Visual Studio I go..

Technorati Tags: ,,,
Saturday, July 19, 2008 12:46:51 AM (Mountain Standard Time, UTC-07:00)  #    Disclaimer  |   |  Trackback
# Monday, July 14, 2008

Recently, I purchased a copy of .  I'm not even going to pretend I've scratched the surface of what ReSharper can do, but I can assure you it's a massive time saver when creating classes from scratch.  I'm furiously plugging away, implementing an ORM for RADE, and to do that I needed to create a lot of classes pretty much from scratch (oh, and do I have a few things to say about that, but that's for another day).  Let's look at a simple example.  To get things started, create a new class.  Select the folder in the solution explorer, and press Alt+Insert:

ReSharper Class Creation

Press enter and you are prompted for the class name.  So Visual Studio has this of course, but this is a small example of some of the time savings you can achieve.  Enter the class name and you start off with an empty class.  Next, lets define a couple of private members.   Let's run with the following example.

   1: namespace RADE.BO.Domain
   2: {
   3:     public class SampleClass
   4:     {
   5:         private Int32 _ID;
   6:         private String _Description;
   7:         private Int64 _BiggerInt;
   8:     }
   9: }

 

Simple class.  Three member variables.  Here is where the big time savers come in.  Next, click Alt+Insert again and you will be prompted with the following options:

Some ReSharper Code Generation Tools

Choose Properties.  You will now be given the option to select one or many fields, set the access rights, read only and virtual properties as well a bunch of others. 

ReSharper Properties Generator

Execute that and all of your get/sets are defined.  My one complaint is that ReSharper is not maintaining the type on the properties.  My Int32's become int, and Int64's become long's.  Apparently this is slated to be fixed.  

So yes, this sample class is tiny, but the time savings on larger classes, or projects full of classes are significant.  The last feature I've been using extensively in this project is the generate constructor tool.  Again, a form is displayed with the defined properties, select the ones you want and boom.  You can create half a dozen different constructors in seconds.  I've created a full object model on, roughly 20 different mildly complex objects in less than an hour, around midnight on a Sunday =)

Some of the other things ReSharper does is suggest code cleanup ideas by removing unused directives, easy execution of , improved code completion.  I encourage you to check it out, .

Technorati Tags:
Sunday, July 13, 2008 11:43:17 PM (Mountain Standard Time, UTC-07:00)  #    Disclaimer  |   |  Trackback
# Friday, July 11, 2008

Since moving to Vista x64 I've had a heck of a time with Oracle clients.  The one thing I could not get working until tonight was ODP with Visual Studio / .NET.  Finally I found a solution.

First, download and install . (Link requires registration)   This should get the 32bit stuff installed.   I'm still using an Oracle 10g R2 server.  You will likely need to grab a copy of the TNSnames.ora for your existing client folder and place it in the appropriate tree of the 11g product home.

This however is not enough to get .NET working with ODP.  Go to the folder where you extracted the zip.  We need to find the Oracle.DataAccess.dll.  This can be found in the file named filegroup4.jar, in the stage\components\oracle.ntoledb.odp_net_2.  Winrar will open .jar files if needed.  Extract the Oracle.DataAscess.dll file.

For now, I've put a copy of this file in my projects lib folder.  I then added a reference directly to this file from all projects that need ODP access. 

Keep in mind - before you ship you may want to remove this reference and ensure that the .DLL file doesn't get included in your build.  This should get your Vista x64 box developing with ODP.

To Oracle - come on guys.  Give us some Vista x64 love!

Technorati Tags: ,,,,
.Net | ODP.NET | Oracle | Vista | x64
Thursday, July 10, 2008 11:00:33 PM (Mountain Standard Time, UTC-07:00)  #    Disclaimer  |   |  Trackback
# Thursday, May 29, 2008

RADE has grown significantly in size and complexity over the past four years.  What started off as a relatively simple classic ASP application has grown to 8+ .NET assemblies, with numerous 3rd party DLL references.  Current R&D is going to further increase the size of the build. In addition to that, we've developed several vertical products on top of RADE which need to be updated as new revisions of the base framework are completed.

It's come to the point where I need to get to a one step build.  The first move in here was to implement in my build process as protecting the assemblies ended up being one of the bigger pains in the butt when building.

So to kick things off, we need to work with MSBuild a little bit.  Originally, I tried using the <exec> call from MSBuild.  This didn't give me the flexibility to loop through the files being generated.  So I started writing a custom build task.  Please read this on building custom tasks if you are new to this.

In summary, I defined a number of get/set methods for the globals I wanted the build engine to set, and in the Execute function I set it up to loop through the passed .DLL files, and execute Protector on each.  After the dlls were processed, they were moved out of the protected folder and the protected folder was removed.  If you are having problems getting your task running, check out this article on .

RADE uses a Visual Studio 2008 to deploy all of the files on build, so to implement the new task we need to do some editing in the project.  Open the project either with a text editor, or in Visual Studio by a right click on the project and choosing "Open Project File".  This part is quite simple.  First ensure that the assembly generated by building your task is in the same folder as the web deployment .wdproj file.  Next we need to add a line near the top of the web deployment project:

   1: <Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">
   2:     <UsingTask TaskName="Landor.Deploy.BuildTasks.RemoteSoftProtector" AssemblyFile="Landor.Deploy.Buildtasks.dll"/>
   3:     <PropertyGroup>...

Here we point the UsingTask call to both the namespace and class of our protector code, as well assembly.  One more change to make.  Scroll to the end of the project and you should see a number of empty <Target> tags.  We need to add some code to the Name="Afterbuild" tag.

   1: <Target Name="AfterBuild">
   2:         <ItemGroup>
   3:             <DLLFiles Include="$(MSBuildProjectDirectory)\Release\Bin\*.dll"/>
   4:         </ItemGroup>
   5:         <RemoteSoftProtector
   6:             Files="@(DLLFiles)"
   7:             ProtectorEXEPath="C:\Program Files (x86)\Remotesoft\Protector\bin\protector.exe"
   8:             ProtectorParams="-neutral -string -cctor -clrversion v2.0.50727"
   9:             BinFolder="$(MSBuildProjectDirectory)\Release\Bin\"
  10:             Exclusions="AjaxControlToolkit.dll;Microsoft.Xml.Schema.Linq.dll;ZedGraph.Web.dll"
  11:         />
  12: </Target>

 

Two things occur here.  First, in the <Itemgroup> tag we are initializing a variable called DLLFiles, and it's getting all the .DLL files in the project's Release\Bin build folder.   Note that this process creates a semi-colon delimited list of full paths and files.

The next thing that occurs is actually calling the build task using the <RemoteSoftProtector> tag.  The tag name should/must match the name of the build tasks' class.  Within this tag, we are setting all of the defined public properties, using the same name as those defined with our build task class.

I've posted Visual Studio 2008 source/projects/solution

.

This concludes a day of fun learning how MSBuild and custom tasks work.  Hopefully it helps you out a bit.  Bugs or comments, let me know.

Technorati Tags: ,,
Thursday, May 29, 2008 6:52:33 PM (Mountain Standard Time, UTC-07:00)  #    Disclaimer  |   |  Trackback
# Saturday, May 24, 2008

When .NET based assemblies go out the door, it's incredibly simple for others to get access to your code.   Download and take a look at what some of your assemblies have to say.  The code visible is likely not going to be anywhere near as elegant as the original.  The comments will be gone.  The gist of what you are doing will be there.  If you would prefer that your work be a little tougher to get at, read on.

Obfuscation was one of my first answers to this problem.  An obfuscator ships with Visual Studio Pro, free and there are many available on the market.  Obfuscation just didn't do it for me.  I once helped a customer troubleshoot problems with one of their software solutions from an unnamed vendor using Reflector and walking through the obfuscated code.  This was really a painful experience, it does make it harder to figure out what is going on - but a friend of mine suggested a product that takes code protection one step further.

Hello .  This product is pretty cool.  If you purchase the protector product you will receive three components.  Salamander .NET Decompiler, .NET Obfuscator, and .NET Protector.  Initially I was processing my assemblies with both the obfuscator and the protector.   Now a days, I pretty much only run my assemblies through the protector.

Once you've processed an assembly with the protector and you open it up in reflector things are going to look a little different.  Here is a little before and after action for you:

Code as disassembled by Reflector 

Now lets take a look at the same code, but after being protected:

image

That's it.  Protector has made all your code go bye bye =)  What's happened here?  As I understand it, Protector compiles all your managed .NET code into native code.  So, yes, is it possible to disassemble native binaries.  The difference here is the height of the bar - with plain .NET assemblies even my grand mother could get my code.  Reverse engineering a native assembly is a different story.  If someone with the skill to do that wants your code - well you must be writing some damn fine code.  It would probably be easier for that kind of person to write it from scratch =)

I've been working on increasing my score lately.  One of my biggies is the one step build for RADE.  That sentence really doesn't do the task justice.  The first step I'm tackling in the one step build is automating the process of protecting my .NET assemblies.  I could not find any resources on doing with with MSBuild.  Once I get it working, I'll post some code.

All that said, I highly recommend you check out Protector if code protection is your thing.  The price is a little bit steep at 1899$ for 1-5 developers - but how much money have you invested in that one little DLL or EXE file?

Saturday, May 24, 2008 5:53:21 PM (Mountain Standard Time, UTC-07:00)  #    Disclaimer  |   |  Trackback
# Thursday, May 15, 2008

With the release of Mapguide 2007 I was really excited about the new API and the significant power that it would give us developer types.  Though I now appreciate the work involved with creating a full object API for all the supported development platforms, I was a little sad to see that only a handful of objects had been created for working with the various entity types available in Mapguide.

One of my first tasks with Mapguide was to add some layers to the map, before the viewer had loaded up, save that map in the session repository and then build a layout for the map - again in the session repository.  I tried various ways of working with the XML provided by the resource  service, and read through many of the e-mails on the topic from the Osgeo list, but I just couldn't get it to work.  So I set out on my mission to get an object based method of getting things done.  First, as per the developer documentation I tried out xsd.exe.  XSD allowed me to get a class skeleton created, but there was a lot of work needed to a rounded API running.   I had been recently investigating the new functionality Microsoft was exposing with LINQ - and I came across LINQ to XSD.  For more information on Linq to XSD the is a good place to start. 

So download and install it.  You will need to have installed first.  In addition to that I'm using Visual Studio 2008 Pro.  I have tried these steps with both Mapguide Enterprise 2008 and  2009.  I have to assume the resulting code will work with Mapguide Open Source as well.

Setting up your project

At this point you should be able to fire up Visual Studio and create a new project.  If you are a VB developer, I'm afraid you're going to have to dive into a bit of C#, as its the only support language right now.  It's not that bad.

The new project window should look a little like this:

image

Choose LINQ to XSD Library and give the project a name.  Once the new project is loaded, create a new folder called XSD.  Browse to your Mapguide 2009/OS 2.0 server Schema folder (on a default installation its c:\Program Files\Autodesk\MapGuideEnterprise2009\Server\Schema).  Take a these files and drag them into the new XSD folder.

Back in Visual Studio, select all of the XSD files.  Look in the property window and change the "Build Action" to be "LinqToXsdSchema".

Building the project

At this point, right click on the project in Visual Studio, and choose build.  You should have 173 errors.  This is caused by having multiple, similar versions of some of the XSDs.  Let's exclude the following files:

  • FdoProviderCapabilities-1.0.0.xsd
  • LayerDefinition-1.0.0.xsd
  • LayerDefinition-1.1.0.xsd
  • LoadProcedure-1.0.0.xsd
  • SymbolDefinition-1.0.0.xsd

Rebuild the project and we should be down to five errors.  I have found that by excluding the following files I was able to get the code to generate:

  • ApplicationDefinition-1.0.0.xsd
  • ApplicationDefinitionInfo-1.0.0.xsd
  • SymbolLibrary-1.0.0.xsd

 

For my purposes, I was not too concerned about being able to work with these entity types programmatically (at least at this time).  If anyone is able to work around and would like to share it, please let me know.

Build the project again, and we will see three new errors.  This time we will need to dig into the generated code to correct them.  For each of the three errors we will want to change the public string name.  For example:

   1: public string DataType {

 

We would change to:

   1: public string Datatype {

 

Change the case of the property name in each of the three errors and we are just about there.  At this point you should have around 42904 lines of code in this file.  Good thing I didn't try to do this manually.   Take a copy of all these wonderful lines o' code, and we're going to paste them into a new class. For the sake of this example, I renamed class1.cs to be OSGeo.Mapguide.Objects.cs and pasted the code in there.  I also wrapped all the code in a namespace to match the file name.

If you need to find the generated code, take a look in the obj folder within your project.  You should find a file named LinqToXsdSource.cs in the appropriate build folder.

Next we need to prevent the XSDs from rebuilding each time.  Select all of your XSD files again, and change the "Build Action" to "None".    Building the project at this point will generate fifty some odd errors.  We can eliminate these by doing a search and replace on global:: and replacing it with an empty string.  Build the project again, and you will find one error.  Simply remove the "global." from the line in question and the project will now build.

At this point, you should have a nice .dll file which you can reference from your projects and access many of the Mapguide entity types using objects.  Be sure to grab a copy of Microsoft.XmlSchema.Linq.dll and distribute that with your new DLL.

For your convenience, I've posted the Project, source and binaries

This project maybe have some issues.  I have worked with LayerDefinitions, MapDefinitions, and WebLayouts - but not tested many of the classes here yet.  If you have any feedback or enhancements you want to share - please let me know!

In the next week I will post some examples on how to build maps and layouts - before the viewer has loaded.

Thursday, May 15, 2008 8:18:11 PM (Mountain Standard Time, UTC-07:00)  #    Disclaimer  |   |  Trackback
# Friday, April 25, 2008

There is a problem with not null constraints and Mapguide Enterprise.  This problem exists in both 2008, and the 2009 versions.  If any columns within your table or view are defined as not allowing null Mapguide will pick these up as key fields.

I found this problem when trying to programmatically retrieve a feature set of  the current selection.  When the SetFilter method on the MgFeatureQueryOptions call was issued I was receiving a  "Not Implemented" error.  After a bit of back and forth with Steve Dang at Autodesk he gave me a list of valid  database property types for the SetFilter call:

   1: //The problem is from the web tier.  Note that the  MgSelectionBase::GenerateFilter method
   2: //will throw an  MgNotImplementedException if the property type of the filtered data
   3: //is not one of the following types: 
   4:  
   5: MgPropertyType::Int16
   6: MgPropertyType::Int32
   7: MgPropertyType::Int64
   8: MgPropertyType::String
   9: MgPropertyType::Single
  10: MgPropertyType::Double

 

This got me looking at my underlying fields, and eventually I noticed in the ODBC data connection the key fields for the table in question contained a  number of columns that just should not have been there.  The problem field was a date column - which would explain why the SetFilter call was throwing and error.  Upon closer inspection I realized that these columns were constrained with "Not Null" constraints. 

So I changed my source database and removed the not null constraints.  Went back to studio to refresh the table - but the columns were still there.  Long story short - there is possibly another defect somewhere in Mapguide around data connections.  They seem to not fully update when you make changes to them.  However, creating a new data connection and pointing to the same SQL server database now shows keys without the null columns.

Moving forward in my code now generated the selection filter and things were good.

I proposed to Autodesk that they auto populate the key fields but then allow the user to modify this list, in addition to correcting the not null constraint issue.   It seems as though all primary and foreign keys are being found for the table/view and added to the list.  Fair enough, however in the view I was working with I had something like 10+ keys (due to the joins of data tables, as well as the needed lookup tables).   In reality - I only was interested in one of those fields.  Filtering based on that one field was enough to uniquely identify the data in question.  I'm not really familiar with the way FDO does things so this might not be possible.

Technorati Tags: ,
Friday, April 25, 2008 5:52:48 PM (Mountain Standard Time, UTC-07:00)  #    Disclaimer  |   |  Trackback