Amptools.Net

simplify your life.

Archive for April, 2008

Thoughts on Developing a Linq To SQL Layer

No Gravatar

Amplify is going to have a Data Namespace that will serve as a basis for dealing with data including, validation, database migrations & fixtures similar to rails and even give some basic patterns to use.  One of these patterns will be an Active Record pattern and another will be a Repository pattern, since the repository tends to favor Linq to Sql.

One of the biggest debates on is whether or not it supports the scenario. Of course many people are still confusing the difference between physical Tiers and virtual layers in code (DAL is a data access layer, not a tier). Linq to Sql can support layers out of the box, depending on how the developer uses the generated objects.   Linq to Sql does not support WCF out of the box and you pretty much have to really massage Linq to Sql in order work disconnected, even within a Web Environment the default tight relationship between an object and the DataContext can be a bit of a pain. Linq to Sql does follow Domain Driven Design heavily.

With Asp.Net Mvc on the horizon, I think it would be proper for a Linq to Sql to have some form of an harness that provides much of the same functionality as possible as the Rail’s Active Record does. Obviously c# is not ruby and a developer can not do everything the same way in c# that you can in ruby.  A good reason to get as close as possible to rails api for active record is to simply help developers who know specific concept like rails active record to hit the ground running with Amplify. 

The reason I see for doing creating an Active Record for Linq to SQL is so that you can wrap validation, business/domain logic and encapsulate it into one object, versus having to know where the separate rules are kept for data, which can create a simpler api for the developer and clue a person to in to what the domain entity is capable of and should be able to do.  This would hopefully shield the developer from being tempted to do the following with Linq to Sql, which could lead to invalid data or even worse. 

	private void Bind() { // bad practice
		using(DataContext db = CreateContext()) {
 			this.datagrid.DataSource = (from o in db.Clients select o);
			this.datagrid.DataBind();
		}
	}

Which is a good reason for Amplify to help provide some basic interfaces and even base classes / wrappers for Linq. Now the question is, what do you support? Do support the linq objects that sqlmetal generates, provide your own CodeGen tool for Visual Studio?  Since generates the partial onPropertyNameChange methods which are crude and does not help to reduce code or really support code reuse. If you support classes that SqlMetal generates, you need to use some form of Reflection or a Linq Expression to do any kind of business rules evaluation of the incoming values.  Do you create your own kind of UnitOfWork pattern and force Linq To Sql to work disconnected and keep track of your own changes, if not what is the best way of keeping track of the DataContext that your object is now tied to? 

And if you do your own UnitOfWork pattern, you have to either add a binary timestamp or int version to the table or you have to keep the intial values of the object stashed or you have to fetch the current object in the database in order to use DataContext.GetTable<T>().Attach(entity, oldEntity); Not exactly what I would call very performant (yes I know, its not in the dictionary, but I like the word performant).

If you have any comments, suggestions, questions, feel free to drop me a line.

Gallio & Mb-Unit 3 With BDD style tests, I mean specs

No Gravatar

Only sky is the limitBDD, Behavior Driven Development, is basically a fusion of Domain Driven Design and Test Driven Development (what is with you developers and your love for acronyms, I’ll never know, maybe it comes from developing software in the government sector?). The basic premise has to do with business value of handing over code that is maintainable and readable specific to their domain, versus an over all process/methodology change like going from Agile to Waterfall. Granted projects like Rspec have added much to the overall terminology that Dan North first came up with (Given, When, and Then). BDD is an attempt at having a Domain Specific Language for code and having a mechanism that supplies the company, business, client, or whoever that must maintain that application, with what the application "should" do given in a certain context, i.e. specifications written in code.

Following to what I previously posted on the OSC blog…with ramping up .net for BDD, and spending time working with and MB-Unit 3.0, and time in thought about BDD in general and how it relates to .Net, I’ve come to some conclusions as I want to set the standard for writing tests/specifications for both Amptools and .

The obvious one is, c# is not ruby. can add keywords to ruby since ruby is a dynamic language and you can pre parse a file that is code, then execute it. C# is heavily tied to the default IDE Visual Studio for most developers and it would be a pain to create your own keywords, but at the same time, typing long sentences and having underscores in your method names that should be Pascal cased according to MS standards is just ugly.

Gallio makes good use of meta Attribute tags such as Mb-Unit’s AuthorAttribute, CategoryAttribute, and TestsOnAttribute. Gallio’s GUI client, Icarus, lets you sort by these attributes for running tests. The DescriptionAttribute however is only visible when running the reports, though it would be nice if it were readable/visible in the GUI as well.

Rspec has a "Describe" keyword that basically encapsulates description for a spec, which is often related to a class somewhere else. You can rename the TestsOnAttribute to become "Describe" and now you can categorize all your specs/tests that tests on a certain class. You can also Describe something in different contexts, to which the DescriptionAttribute can help you describe in what context you are using writing this specification for, which would replace the nested "describe" keywords in rspec.

Obvious Replacements would be renaming FixtureSetupAttribute to "BeforeAll" for Rspecs "before(:all)", FixtureTearDownAttribute to "AfterAll", SetupAttribute to "BeforeEach", and TearDownAttribute to "AfterEach". Rename the TestAttribute to "It", DescriptionAttribute to "Should", AuthorAttribute to "By", and CategoryAttribute to "Tag" (since we’re in that web 2.0 tag everything phase.

What you might end up with is something below, which is a code specification for a "ValidatePresence" class which comes from a localized prototyping version of Amplify that I have on my local drive.

namespace Amplify.Data.Validation
{
	#region Using Statements
	using System;
	using System.Collections.Generic;
	using System.Linq;
	using System.Text;

	using MbUnit.Framework;

	using Describe = MbUnit.Framework.TestsOnAttribute;
	using InContext = MbUnit.Framework.DescriptionAttribute;
	using It = MbUnit.Framework.TestAttribute;
	using Should = MbUnit.Framework.DescriptionAttribute;
	using By = MbUnit.Framework.AuthorAttribute;
	using Tag = MbUnit.Framework.CategoryAttribute;
	#endregion

	[
 		Describe(typeof(ValidatePresence)),
 		InContext("should validate the presence of a value."),
 		Tag("Functional"),
 		By("Michael Herndon", "mherndon@amptools.com", "www.amptools.net")
	]
	public class ValidatePresenceObject : Spec
	{
		[It, Should(" have a public default constructor. ")]
		public void InvokeConstructor()
		{
			ValidatePresence obj = new ValidatePresence();
			obj.ShouldNotBeNull();
  			obj.RuleName.ShouldBe("ValidatePresence");
		}

		[It, Should(" validate the value passed to the object. ")]
		public void ValidateValue()
		{
			ValidatePresence obj = new ValidatePresence();
			obj.DefaultValue = "";
			obj.Validate("").ShouldBeFalse();
			obj.Validate("Has Value").ShouldBeTrue();

			obj.If = (value) => !string.IsNullOrEmpty((value as string));
			obj.Validate("").ShouldBeTrue();
		}
	}
}

In case you are wondering where all the ".Should" methods are coming from, they are c# extension methods that I’ve created that are stemmed from Assert methods found in the typical testing library such NUnit or Mb-Unit. I was using NBehave for the extension methods, but I didn’t care for the tight coupling with Rhino Mocks, especially when I’m going to be using Moq as the Mock Object Library.

Now in Icarus, I can sort by TestsOn, Category and Namespace, and in the Reports generated by Gallio, I get all the above, plus the Description. Sooner or later, it would be wise to add a plugin to Gallio to generate a specification type of report, that would generate specifications for anyone would wanted to use Amplify or Amptools.

currently listenting to.. D12 on Devil’s Night performing Purple Pills

Simplicity

No Gravatar

Working on the complexity that is always indirectly implied by simplicity.

Simplicity. "Simplicity is the property, condition, or quality of being simple or un-combined. It often denotes beauty, purity or clarity." en.wikipedia.org/wiki/Simplicity. It is very rare in today’s world for anything to really be simple from the inside out. Often, when someone states a simple "truth", we automatically understand the statement without really tracing back how much we had to learn and gain in order to obtain the complex knowledge to understand something that sounds simple when communicated out loud.

You probably have an idea of where I am going with this. Very few things are as simple as they seem or should be. Anyone who has worked in the software industry or any other major industry for any length of time knows how it always sounds simple when someone utters it, but that is rarely the case, because of all the implied complexity and all the details that are often not apparent in that statement.

I’m currently employed with Opensource Connections, to which one of their strongest core components is developing thought leadership. From that, stems the B.H.A.G (big, hairy, audacious goals), a project or multiple projects that develop thought leadership. Now before anyone jumps to conclusions that this site or the opensource projects that I’ve been working on, is just to fulfill some quota, it’s not. On I’ve been wanting to write a .Net framework and tools that applies patterns and practices that allows  underrated within the .Net community. Or the framework could be sufficient in itself. But the biggest part of this that I want to accomplish is bringing Simplicity to everything the framework touches on.

I’m calling the framework "Amplify" and the tools … wait for it….. …..drum roll….. "Amptools" (ugggh naming conventions, but it beats Microsoft naming conventions). The idea in mind is that the framework and tools should amplify your project and its output. Probably the biggest way of keeping simplicity is "convention over configuration", but that is not always plausible, so convention should offer a way to be changed to fit the developers environment.

Now, semi off-topic, one of the simplest ways to encourage use of other source libraries in .Net is unit testing code. However, since the concept of BDD is fairly new, but seems worth exploring, I have decided to take this approach, while leveraging Gallio, the neutral testing platform, in its current alpha state, along with Mb-Unit 3.0. More on this in the next post.