2010/10/28

GetAssemblies missing dll's

I have a couple ASP.Net MVC web applications that allow additional functionality by dropping new class library dll's into the bin directory.  This causes new options, tools, products, workflows, etc to be enabled to the user with just a pushing out a new class library.  We've moved away from using an DI/IoC tool (StructureMap/Castle Windsor) because of seeing some memory leaks and having some maintenance issues of the xml files needed to use them.

Instead I decided to go the route of using existing functionality built into the .Net framework.  There is this nifty little static method AppDomain.CurrentDomain.GetAssemblies() which:
Gets the assemblies that have been loaded into the execution context of this application domain.
So, I figure this being ASP.Net, all the dll files in the bin directory would be loaded up, right?  I run the solution and a bunch Assemblies are returned (mscorlib, System.Web.Mvc, Stuff.I.want.dll, More.Stuff.I.Want.dll) page loads and I can see everything it there and happy. A bit more testing happens and then check-in so it gets put out on the web server.
I run through some testing there to make sure there is no real differences between IIS7 and Visual Studio development web server.  Everything looks great. I've removed some external dependencies, lowered the memory footprint, and eased readability. Fantastic! Time to turn it over to have others really kick the tires.

A couple hours go by and then it happens. "Hey Paul! I'm not seeing any of these options I had the last time I opened the page." So I look, the dll's are there.  There were no other code changes to remove them. Let's run local.  Everything looks fine.  I check that results from this particular call are being cached. Everything seems fine.  I change some methods from static to instance, just in case, and deploy.

Again, everything is going along just fine, until the next morning. "Paul. Seriously, are you messing with me? These options are gone again." Me: "%&$(*$%" Directory looks fine. Ok, going to move some stuff out of extension methods and directly into the main assembly for this backend assembly. Lather, rinse, repeat.

Time passes... "Paul, WTF?" Me: "Are you friggin kidding me?" Nothing, NOTHING, is static now in my code.  Nothing is in an extension method, I am very close to having all this functionality in one big DoThisCrap method.

To the Googles!!!

You remember that "Gets the assemblies that have been loaded into the execution context of this application domain." part earlier? Yeah me neither.

So what was happening, as best as I can tell, was the fresh code right after a deployment (or every time I opened in the VS dev server) ASP.Net loaded every dll in the bin as I hoped.  On subsequent page visits, ASP.Net learned that some files were not needed on the last load and no code was directly instanciating them so they weren't loaded. This means they didn't show up.

What to do? Well, we can get the current directory from AppDomain.CurrentDomain.BaseDirectory property.  From there it's a simple System.IO.Directory.GetFiles call to plow the directory with various search options.

/*
this can be pointed to specific sub folder using string.format
*/
var path = AppDomain.CurrentDomain.BaseDirectory;

/*
you can add file name matching criteria here if the assemblies you are looking for match a naming convention
*/
var files = Directory.GetFiles(path, "*.dll", SearchOption.AllDirectories);

and now we can perform logic on the files array.

Since we are looking directly at a folder path, there is no issue of whether previous runs loaded the assemblies into the AppDomain.  However, there is the additional cost of going to disk to get results.

2010/10/27

Congratulations! You just broke the team!

Infighting. Every team has it to some point. The testing team complains that the developers screwed up the application. The developers blame the business analysts for incomplete/incoherent requirements. The BA’s blame the testing/dev groups for misinterpreting the requirements or interpreting them instead of asking for clarification. The project manager blames everyone for slipping deadlines.

Some conflict is expected within any group. There are, however, lines that need to not be crossed. We are all part of this thing for a reason. Let’s give each other a bit of respect and we can get through our day-to-day much easier. Mutual respect is required for all silos/individuals on the team.

Saying to external teams that you have no confidence in one of the internal teams to deliver on what they are paid to do is incomprehensible. Questioning a team members motives on how they spent a vacation day that was scheduled weeks in advance is ludicrous. Demanding that other teams work nights and weekends when you don’t do the same is selfish. Throwing a fit when an individual says “NO!” to working over a holiday weekend because you don’t celebrate the same holiday is appalling.

Below is a brief list of what is being halted whenever I have to deal with this infighting:

  • I investigate new methodologies and technologies
  • I scrutinize every line of code
  • I monitor data page utilization
  • I remove redundancy
  • I optimize methods and queries
  • I normalize datasets
  • I take long running processes down to a tenth their initial time
  • I plan for scale
  • I visualize data sets and workflows the way most people see pictures
  • I read countless blogs, tweets, message boards
  • I teach more junior developers how to use existing frameworks
  • I collaborate with my peers
  • I document the system
  • I design new features
  • I prioritize deliverables
  • I fix bugs
  • I update data
  • I spec hardware
  • I evaluate new software
  • I verify we are licensed properly
  • I write .Net
  • I read Java
  • I understand PHP, ForTran, COBOL and more
  • I relate the data
  • I connect the networks
  • I make the impossible possible
  • I tell you when the impossible really is impossible
  • I can *DD the hell out this shit
  • I can make fat objects light and anemic domains rich
  • I’ve came in early, stayed late, worked weekends and holidays

I am Paul Montgomery. I am good at what I do. I do this shit for a living because I am good at it. I am a pretty damned big deal. I do all I can to surround myself with highly capable people. I will not tolerate treating any member of my team without respect.

2010/02/02

Name That Caption Contest

Tom LaRock, yes THE Tom LaRock, is running a Name That Caption Contest over on DBASurvivor.com. The winner gets a copy of his book by the same name (catchy, eh?).

So I'll be posting my captions here starting with a rather obvious:
  • I felt a great disturbance in the data center... as if millions of SPIDs suddenly cried out in terror and were suddenly silenced

2010/01/18

Spitting out the KoolAid

85% code coverage
5000 unit test passing
Red. Green. Refactor.

We've all heard the TDD folks spewing comments like this on blogs, twitter, or facebook. Quite frankly, I've had enough. I've been on agile teams (little 'a' agile as there is a difference) and yes it works much better than the good 'ole waterfall methodology. However, TDD is NOT a requirement of being an agile team. Actually, I've seen where having your tests up front and coding to the tests can make you less able to make changes to your project.

If you're not driving your design from tests, what is driving your design?

How about the business requirements and chosen technologies? If you start limiting your design decisions by their testability, you can miss out on some great emerging technologies (try finding anything on unit testing app fabric (velocity/caching).

Making TDD your meal ticket.

I'd say learn new features available in your current language, learn a new language, refresh basic OOP design principles, learn about database design (or UI, or web service, or security, blah, blah, blah). There is always something new to learn methodologies are included but you really shouldn't limit yourself.

Write less code.

I call bull$#!%. So the red/green/refactor can potentially limit you to only writing exactly the methods you need but there is the rub. You have to continually make sure you are not future coding or you lose the "write less" mentality. For starters the "less" code has the addition of the test code. Also, I see many technologies, tools, and patterns being bundled to the project by the TDD evangelists. Mocks, Dependency Injection, Object/Relational Mapping, Inversion of Control all tend to added "bonuses" to the end product. So you take your desired functionality and you wrap all these layers of fluff around them. Each tech and tool requires bending your project to the way the tool needs and typically add new files/projects to be added to the end solution (interfaces, repositories, factories, .hbm.xml, .castle, and on and on). Sounds to me like the promise of "less" leads to more.

Assuming everything else works, does this do its job?

Sounds great doesn't it? We break down our code into these tiny bits and we put a loader over here, a translator over there, we dumb down the classes to base object so we can reuse them in other projects (which NEVER happens). We put the domain classes in one project, put the interfaces in another, have another project for the business logic (because our objects don't know how to do anything with itself). And since we have mocking set up, we stub out the calls of all the inter-connections so we don't actually have to see the parts work together.

Who cares if Billy plays nice when he's at the park? He gets along so well with his imaginary friends.

So I shouldn't test my code?

I'm not saying that. There are very good reasons to do testing. Items behind a service call is a good candidate for putting up some tests. By its nature, the service call is disconnected so slamming the call with numerous inputs is straight forward and easier than a testing UI. Additionally, items with a great deal of logic branching or computations do well. Also, anything that has surfaced as a bug more than once. More importantly, UI testing (automated or manually) covers more of what matters... what the user experiences. It doesn't matter if your Is_it_a_dog tests pass because it has 4 legs and barks. What happens when the user is looking for a cow? TDD evangelists whould say you would make tests for a cow as needed. What about a horse? A turtle? A lorikeet? We know that the test suite has now become the pig.

Seeing the forest through the trees.

So we have now bloated up our number of tests to cover all these scenarios while adding no real functionality. We've changed the tests and the real code to meet new business requirements or add functionality. And yet through it all, the TDD tribe will stick to the tests until one crucial point. When a development team is confronted with 200 development hours and only 150 available hours they will try to push the timeframe back or shrink the feature count. When neither of these are possible due to contractual or regulatory requirements, they say screw the testing and start slinging bits in every way possible. If TDD was so much of a time savings, why do you see teams abandon in what should be its golden hour?

TDD isn't coding with seatbelts. You're tests don't keep you from making mistakes. You'll still misinterpret requirements (and have to change it in at least one additional place). You'll never get enough fringe cases to match your users day-to-day interaction. Testing the individual units makes no guarantee that the system, as a whole, works together as needed. So in many cases, TDD is purely a mastorbatory exercise.

I am currently working to remove many of these practices out of my current project because they have done nothing but degrade system performance and added confusion to the project. I'll take a rich domain objects with a real inhertence model that know how to load, save, and translate themselves. Then I know that I can do more with less code and I can make changes to the objects when the requirements change without jumping through some 30 different base, controlling, and god classes after re-working dozens, hundreds, or thousands of tests.

If TDD is working for you, great. If not, don't feel bad. It's not the silver bullet that it has been touted as.

Comments