Wiring Up The Membership Provider With StructureMap

I spent yesterday retrofitting into an ASP.Net MVC site that I wrote earlier in the year. I ran into a number of minor issues that made me stop and think, and decided to post them here for future reference.

I had already added a constructor to each of my controller classes that allowed services to be passed in as parameters (as it improves testability), so was pretty well prepared for letting StructureMap AutoWire the services as needed.

The site consumed implementations of three interfaces I had defined:

  • IHoldSettingsForTheSite
  • ILogEvents
  • IAmTheSiteRepository

I configured default instances of the implementations in the BootStrapStructureMap procedure which I called from the Application_Start method in the Global.asax:

   1: private void BootStrapStructureMap()
   2:         {          
   3:             ObjectFactory.Initialize(rep =>
   4:             {
   5:                 rep.ForRequestedType<IHoldSettingsForTheSite>().TheDefaultIsConcreteType<Settings>();
   6:                 rep.ForRequestedType<ILogEvents>().TheDefault.Is.OfConcreteType<EventLogging>().WithCtorArg("sourceName").EqualToAppSetting("ApplicationName");
   7:                 rep.ForRequestedType<IAmTheSiteRepository>().TheDefault.Is.OfConcreteType<Repository>().WithCtorArg("connectionString").EqualTo(ConfigurationManager.ConnectionStrings["OpenFields.MainSite.Data"].ConnectionString);
   8:             });            
   9:         }

Good times… all was fine until I tried to call a method on a controller that required authentication.The following exception was raised:

StructureMap Exception Code:  202 
No Default Instance defined for PluginFamily AssenblyName.Controllers.IFormsAuthentication, AssenblyName, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null

Where AssemblyName is the name of my applications assembly.

I’d originally built the site using the “out of the box” AccountController class which is added by default in the ASP.Net MVC project template. This class calls a MembershipProvider object to provide for account authentication.  I’d configured the application to use the ActiveDirectoryMembershipProvider in production and I wired up a dummy MembershipProvider class for use during development and testing.

Within the AccountController.cs file there are a number of other objects declared:

  • IMembershipService
  • IFormsAuthentication
  • AccountMembershipService (Implements IMembershipService)
  • FormsAuthenticationService (Implements IFormsAuthentication)

Personally I think its a bit smelly holding them all in one file but they’re helper objects built to aid testability of the AccountController class and won’t be used anywhere else. I configured default instances of these interfaces and pointed them to these to the Services objects that implemented them giving me this:

   1: rep.ForRequestedType<IFormsAuthentication>().TheDefaultIsConcreteType<FormsAuthenticationService>();
   2: rep.ForRequestedType<IMembershipService>().TheDefaultIsConcreteType<AccountMembershipService>();

When I next ran the app, the following exception was then raised:

StructureMap Exception Code:  202
No Default Instance defined for PluginFamily System.Web.Security.MembershipProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a

The cause of this was from not declaring an instance of a MembershipProvider model. This really threw me initially as I knew that the the wiring up of the MembershipProvider was handled by the membership section of the web.config file:

   1: <membership defaultProvider="DUMMY">
   2:   <providers>
   3:     <clear />
   4:     <add name="DUMMY" type="OpenFields.Dummy.MembershipProvider, OpenFields.Dummy" />
   5:     <add name="AD" type="System.Web.Security.ActiveDirectoryMembershipProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" connectionStringName="ADConnectionString" />        
   6:   </providers>
   7: </membership>

On further investigation, I soon realised that although the membership provider wiring is still handled by this config section and that the MembershipProvider is an abstract class, StructureMap still injects the implementation to use. (OMG this is powerful!)

Basically, we’ve got to tell StructureMap to use the default membership provider for the application. This can be easily achieved by adding the following line into my BootStrapStructureMap method:

  rep.ForRequestedType<MembershipProvider>().TheDefault.IsThis(Membership.Provider);

I couldn’t find many posts on this scenario so I hope this helps anyone in this same predicament!

Get Your Build Under Control

If you’ve followed this blog in the past you’ll realise that I’m a real advocate of and in particular using during the build and environment creation process. Come to think of it, if I could write a Nant script to wash my car for me, I would have done it by now!

 

If you don’t use a CI system, I can’t recommend setting one up enough. I currently use which sits on a virtualized Windows 2008 server (my build server) but this post isn’t about evangelising CI, its about a change I’ve made to how I use it, which saves me time and will hope fully be of some use to you.

The image below outlines the folder structure I use on my build server:

branch

Notice the build-nnnnn folders which are separate build instances.

A new build instance begins automatically after I check some content back into source control in the following order,

  1. The latest copy of the branch is checked out from source control into the “working” folder
  2. Using the , I build a number of predefined solutions in the working folder are built.
  3. A Nant script held in the “scripts” folder is then ran which carries out the following tasks:
  4. Generate a build instance folder containing the “deployable”, “source” and “tests” folders.
  5. Run unit tests in the build instance test folder.
  6. Package all deployable assets up into the deployable folder.
  7. Deploy assets to a demo environment.
  8. Email me to let me know the build has passed(hopefully) or failed.

I’ve stuck with this same process for over a year now but noticed a few areas where things can be improved upon to save time. I’ve spent the last week or so adding some new features to an application I manage. I created a branch and setup a cruise control build as above and began work. Along the way, I created a new solution, added some existing projects from the codebase and created a few new ones. I refactored a couple of classes and moved a number of them out into another new project so they could be reused by other parts of the code base. Being a good little agile programmer, I obviously created accompanying unit test projects and also added them to the new solution.

Once I had a good local build and all tests passed, it was time for me to check my work in.

However, as I had added more solutions and unit tests to the code base, I realised I would have to amend the build scripts so the new solution would be built and the new unit test project would be tested.  So prior to checking in, I had remotely connect to my build server to update the relevant Nant script and project entry in my CC.Net config file. Once I was happy the build file and Nant scripts were ready to rock, I could then go back to my development machine and check my working copy of the feature branch in.

 

I was finding this context switching from dev environment to build environment disruptive and more importantly, I felt it was detracting from the amount of time I could dedicate to actually develop.

The issue finally came home to me when I merged the feature branch back into the trunk and had to copy and paste the changes from feature branch scripts to the trunk scripts. This process not only held up the TTL (Time To Live) but copying and pasting is always the point where I’ll screw up and introduce an error of some description.

Does any of this sound familiar? I spoke to @jonhilton regarding this and although he uses Teamcity and MSBuild, it sounded like he’d encountered the same sort of issues and it suddenly dawned on me.

 

Develop The Build As Part Of the Feature

By moving as much of the build process into the Nant script and moving the the Nant script into the the branch itself, it qualifies for all the benefits all other source controlled assets do:

  • Versioning
  • Merging
  • Reverting
  • Tagging

and by keeping the Nant scripts within the development environment (see image below), I can work on them locally so no context switching to the the build machine is necessary. All you need to do then is configure the branch build in your CC.Net project entry to run the Nant script held in the build instance folder.

SolutionExplorer

Keeping the build file within the solution helps you think of the build as part of the feature and also gives you quick and easy access to the build file for when you need it.

The real benefit is realised when you merge the branch back into the trunk and the changes are automatically merged into the… you know where I’m going with this!

The last piece of the puzzle concerns building the solutions (step 2 above) as part of the build process. I now carryout the process of running msbuild against the solutions from within the Nant script itself.

 

Implementing Presto 3.0 - Gotcha #4

This is just a quick one to file under “remember” if you need to change the SMTP settings InMagic Presto.

Presto sends emails out using the Presto services component but the SMTP settings are stored in sites web.config file. If you change the SMTP settings in the web.config file, you must restart presto services for the changes to be implemented.

The learning curve just never levels out…

Payback Time

We’ve been moving sites/servers/databases and services to a new infrastructure this last week or so. Not only have we had to factor in time for the physical moves, there’s also been the added delay and complication of paying back 3 years of technical debt.

Technical debt is built up every time you are presented with two options of getting the solution implemented or at a lower level, writing the code it self. At the time, when pressure is on to implement and deliver, the easy/messy way seems best but this can easily come back and bite you in the ass when things start to go wrong or as I’ve been experiencing this week, when systems get moved around.

The most common piece of technical debt I’ve been paying back on this week has been refactoring systems to move hard coded database connection strings into configuration files where they can be easily changed as necessary.

I know of at least one system somewhere in another organisation that had the Value Added Tax (VAT) rate hardcoded into its finance systems. I hope they had an enjoyable time late last year when the rate dropped to 15%!

But enough of all this ranting. I’d like to thank the “programmer” that hardcoded the connection strings on the systems I’ve been refactoring this week. Your ineptitude has kept me and my family fed for another week. I only hope that you are now doing something less technical and that your next poo is a pineapple…

Running Multiple Instances of SQL Server

or “so you think you’ve got problems!”

We’re currently updating our server infrastructure at National Rural. As an interim measure I’ve got to run an instance of SQL-Server 2005 and SQL-Server 2008 on the same box. Both instances are consumed by web apps and the box has a firewall installed. I need to connect to both instances via SQL-Server management studio but ran into some pretty bizarre gotchas which I’m going to list here for future reference.

Summary

For those that need the quick fix, here’s how I got it running

  1. Run each SQL-Server instance on its own TCP port.
  2. Ensure the required ports are configured for TCP connections on the firewall.
  3. Open port 1433 for UPD connections.
  4. Ensure the firewall ports are configured to operate using the narrowest scope possible to fulfil your needs.

To configure a SQL Server instance to run on a specific port, open the SQL Server configuration manager, ideally on the local machine that the server instance is running on.

  1. Select SQL Server Network Configuration.
  2. Select Protocols for the named instance of the server you wish to configure.
  3. Double click TCP/IP and select Enabled.
  4. Set “Listen All” to yes in the Protocol tab.
  5. On each IP Addresses listing, ensure all IP Entries have empty values for the TCP Dynamic Ports and TCP Port values
  6. In the “IPAll” section, ensure TCP Dynamic ports is empty (NOT 0!) and the TCP Port value is set to the port number you wish the server instance to listen on.
  7. Select “Apply” and restart the SQL Server instance in question.

 

Common Pitfalls and Gotchas

There are a number of connectivity issues you can run into if you’re SQL-Server version is express and developer edition as by default, they are configured out of the box to not accept Remote Server connections, and there are plenty of articles to get round this issue like this one here.

The issues listed below and error messages occur when the server is already configured to allow remote connection but you are still running into issues. If like me, you had a default instance of SQL server running, whatever version, it would have grabbed TCP port 1433 to listen on and all is well with the world. Allowing the firewall to allow TCP Connections for this port number is all you need to do to connect remotely using SQL-Server management studio. I had a 2005 instance running as the default instance on my dev box but then needed to install an instance of 2008 to run side-by-side with it. This instance I named SVR2008 (They don’t pay me for originality!). I could connect to it locally via SQL Server Management Studio and all was well with the world. The problems arose when trying to connect remotely…

ObjectExplorer

Figure 1 above shows my two instances of SQL-Server on the same machine when connected to locally in SQL-Server management studio. Note that the default instance is version 9.0 – a SQL-Server 2005 instance.

When I try to connect remotely to this box now from another machine using SQL-Server management studio, I can see the default instance but not the named instance. This is because, initially, the named instance of SQL-Server will be configured to run on a dynamic port - basically when the SQL-Server instance starts, it grabs a dynamically allocated TCP port to listen on and this port will be different every time the server instance restarts. If that is the case, the firewall will block the connection and SQL-Server management Studio will display the following error.

Cannot connect to servername\instancename.

------------------------------
ADDITIONAL INFORMATION:

A network-related or instance-specific error occurred while establishing a connection to SQL Server. The server was not found or was not accessible. Verify that the instance name is correct and that SQL Server is configured to allow remote connections. (provider: TCP Provider, error: 0 - A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond.) (Microsoft SQL Server, Error: 10060)

For help, click: http://go.microsoft.com/fwlink?ProdName=Microsoft+SQL+Server&EvtSrc=MSSQLServer&EvtID=10060&LinkId=20476

To solve this issue, configure the SQL-Server instance to use a specific TCP Port (see above).

 

If you get the following error message when trying to start the second db instance:

Cannot connect to servername\instancename.

------------------------------
ADDITIONAL INFORMATION:

A network-related or instance-specific error occurred while establishing a connection to SQL Server. The server was not found or was not accessible. Verify that the instance name is correct and that SQL Server is configured to allow remote connections. (provider: SQL Network Interfaces, error: 26 - Error Locating Server/Instance Specified) (Microsoft SQL Server, Error: -1)

For help, click: http://go.microsoft.com/fwlink?ProdName=Microsoft+SQL+Server&EvtSrc=MSSQLServer&EvtID=-1&LinkId=20476

..you may have not opened the firewall wall for the port the server is listening on. Change the TCP port of the named instance to a different port and restart the db instance. Ensure that that port is open for business on the firewall though and that port 1434 is configured for to accept UDP connections.

Like wise if you get this message:

Cannot connect to server\instance

------------------------------
ADDITIONAL INFORMATION:

A network-related or instance-specific error occurred while establishing a connection to SQL Server. The server was not found or was not accessible. Verify that the instance name is correct and that SQL Server is configured to allow remote connections. (provider: TCP Provider, error: 0 - A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond.) (Microsoft SQL Server, Error: 10060)

For help, click: http://go.microsoft.com/fwlink?ProdName=Microsoft+SQL+Server&EvtSrc=MSSQLServer&EvtID=10060&LinkId=20476

The only difference here is that you’ve not opened the listener port for the db instance but you’ve opened port 1434 for UDP connections.

UDP port 1434 is used by when determining the named instance of the server you’re trying to connect to, which makes perfect sense as you don’t need it open when accessing the default instance (in figure 1) this would be W2003-DEV-2.  However, SQL-Server seems to assume that any db instance that sits on port 1433 is the default instance. To prove this, swap the TCP ports used by the default and the named instances on the server and voila, on remotely connecting to the default instance of the database instance, you’ll actually be seeing the named instance. You have been warned!!!

 

ObjectExplorer2 Figure 2. Note the version number of the default instance. We’re actually looking at the same db instance in both connections. That’s because the SVR2008 instance is running on port 1433. In this scenario, we can’t actually connect to the actual default instance in this way.

Tortoise SVN Bizarre Tree Conflicts When Reintegrating A Branch

I use Tortoise SVN as a client application to manage a Subversion repository hosted by CVSDude.

If like me you blindly “hit the tit” when you see this on your machine:

  tortoisesvn

and think little else about upgrading your version of Tortoise-SVN client whenever you can… FFS STOP!

Version 1.6.0 of the SVN-client app introduced enhanced handling of tree conflicts. A tree conflict can occur when the following happens:

  • Two developers check out branch 1.
  • Developer 1 updates a file in the branch and commits the changes.
  • Developer 2 deletes their local copy of the file then updates their working copy prior to checking back in.
  • A tree conflict is detected on that file which must be resolved prior to checking the working copy back in.

Lets cut to the chase:

Don’t use version 1.6.x of Tortoise SVN client with SVN server of less than 1.5.6. It will bring pain and suffering.

Symptoms of using version 1.6.3 of Tortoise SVN and SVN Server with a version of less than 1.6 include:

  • Tree conflicts detected that don’t make any sense - files that I know for a fact haven’t been changed on the trunk are showing up as tree conflicts when merging a feature branch back in.
  • “Successfully” merged files don’t contain the expected updated content.
  • General stress and anger to the developers’ colleagues and spouse.
  • General bad language in random tweets on the matter.

Downgrading the version of Tortoise SVN on my development machine to version 1.5.9 fixed the problem for me and I successfully merged a branch back into the trunk with no problems. I hope this saves someone the three hours of hacking about that I endured yesterday…

Grokking up for 70-536

Robs post regarding certification couldn’t have sparked more debate at a better time for me as I had just decided to start studying for my MCPD certification as an ASP.NET Developer 3.5 on Visual Studio 2008.  Reading the comments to Robs post, it’s apparent that there are certainly mixed feelings in the .NET community regarding the MCPD qualification to the extent that some software houses instantly bin the CV’s of applicants that hold an MCPD – a pretty narrow minded attitude IMO.

 

I wanted to undergo a self-managed personal and career development process (as HR types would describe it) and had considered going back to college on a part-time basis to further my academic qualifications in business IT. However, I think that studying for an MCPD qualification would be a better fit for my own development needs at the moment.

 

I’d actually considered studying for an MCPD for a year or two now but didn’t follow through with it for a number of reasons:

  • Why bother getting certified in ASP.Net 3.5 when it’ll be superseded in two years time?
  • I’ve got this far without being certified. How will this help me?
  • It’s just too much to learn for an exam when I’m only going to use a small portion of what I learn for my day to day job.

Despite all these arguments which we’ve all heard and read a thousand times before, I’m still going for it, for one simple reason:

I think obtaining an MCPD is the best way to start bettering myself as a developer.

I say “start” as I certainly don’t think for one minute that being an MCPD will elevate me to excellence – and I’m sure those of you that know me would agree! I do however, think that the things I’ll learn on the way towards becoming certified will help me use the .NET Framework to develop solutions using the right tool for the job and give me a wider, though not necessarily deeper understanding of the MS stack.

 

 So for anyone else just starting to study for 70-536 in particular, here’s where I am at the moment.

  1. I’ve built a list of links on Delicious that you might find useful and I’ll add to as I go along
  2. I’ve got my head in these books  MCTS Self-Paced Training Kit (Exam 70-536): Microsoft® .NET Framework—Application Development FoundationProgramming Microsoft® Visual C#® 2008: The Language (PRO-Developer)
  3. I’ve started working through the MCTS book and reading the relevant chapters in the second book to augment it while writing a couple of sample apps to support the topics I’d been studying.

If I stumble on any WTF moments or any moments of clarity, I’ll blog it to help anyone else out in the same position. Any advice or further ideas regarding the exam would certainly be welcomed.

 

I’m not sticking to a rigid study schedule for this exam (having a twenty month old son kind of knocks any pre-planning on the head!!). Being goal oriented, I’d normally set a date that I want to take the exam by and pressurise myself into cramming near and nearer to the exam date, but the goal for me is to learn and expand my knowledge base so I’ll take the exam when I’m good and ready.