"Working on the complexity that is always indirectly implied by simpilicity."

Simple Log in Amplify

As many people know rails has a simple logger inside the framework which really only outputs to the console. This comes in handy to see SQL output of your models, benchmarks and other cool little things inside the rails framework. 

Of course people in the .Net realm tend to want things that scale and yet simplified for them.  So output only to the console won't fly in larger projects.  There is log4net, but you don't want to have it tightly coupled to the system, this caused an issue to one project that I worked on while still working for Vivus Software before I came OSC. Where the framework and project both expected a certain version of Log4Net and there was no wrapper to put something else in place if need be. 

So the solution was to Build small static Log class, that takes a list of an interface ILog (different than log4net's) and then use that interface to build a wrapper around using the root Logger for log4net. This way people can still build their own loggers for amplify or build their own Appenders for Log4Net and amplify will still be able to leverage this. Of course there is also conditional symbol LOG4NET in amplify if you wish to build the amplify framework without any dependency on the log4net library.  

To me this is more like the Console.WriteLine that is needed for a class library vs what log4net is typically used for in an application where it also spits out the type information of a class. To help with the testing using mock object is the which uses the Lambda expression and gets rid of all that crazy record/playback junk to which I loathe. 

		public void Test()
		{
			var id = 0;
			Log.Sql("SELECT * FROM test");
			Log.Debug("The id is  {0} ", id);
		}		


		[It(Order = 2), Should("have a debug method that logs debug statements")]
		public void Debug()
		{
			var calls = new List<string>();
			var log = CreateMockLog();

			log.Expect(o => o.Debug(Moq.It.IsAny<string>(), null))
				.Callback((string s, object[] args) => { calls.Add(s); });

			calls.Count.ShouldBe(0);

			// simple and easily called from anywhere... and lets you 
			// format messages like 
			// Log.Debug("item id: {0} could not be saved", id);
			Log.Debug("debug", null);
			calls.Count.ShouldBe(1);
			calls.Contains("debug").ShouldBeTrue();

			Log.IsDebug = false;

			// its turned off so it won't output anything
			Log.Debug("debug", null);
			calls.Count.ShouldBe(1);

			Log.IsDebug = true;
		}

		private static Mock<ILog> CreateMockLog()
		{
			var log = new Mock<ILog>();
			Log.Loggers.Clear();
			Log.Loggers.Add(log.Object);
			return log;
		}

Though keep in mind, one of the more trickier things to mock is the use of a method with the "params" keyword. I had to used a callback that you pass in an object array (object[] args) and I passed in null, otherwise the callback would not fire, and Lambdas don't allow the "params" keyword. Once that was figured out, I was able to use moq successfully to test the Log class successfully.

Labels: , , , , , , ,

Gallio and Mb-Unit release v3.0.4

You can find many of the new features over at Jeff Brown's blog.  Some of the cooler features of note is the integration with the visual studio testing system, wrapping testing for exceptions into a delegate, and data store called Ambient, in which you can store state for your tests.  I've integrated this into amplify which is again, now on GitHub. I did run into a few lil issues when setting this up though....

The biggest issue was finding out how to turn a project into a test project in order to get the visual studio integration working for Gallio. Basically you need to make modifications to the .csproj file and add an XML element of <ProjectTypeGuids> into the first <PropertyGroup> of the file. 

<ProjectTypeGuids>{3AC096D0-A1C2-E12C-1390-A8335801FDAB};
{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} 
</ProjectTypeGuids>

After this, I could get the Gallio tests showing up in visual studio.

Gallio-Test-View

Now this coupled with really helps with the testing process especially since with certain versions of Visual Studio, Test Driven .Net will let you run visual studio's code coverage with Gallio.

CodeCoverage

Again, one of the cooler features was the improvements to Mb-Unit's Asserts (which did change the API, but its all good, cause I wrap the Asserts that I use in BDD style mixin Methods, so I just need to change them in one place). The one really change of note would be adding Assert.Throw and Assert.Throw<T>, to which you can wrap throwing an exception into a delegate.

WrappingExceptions

All in all nice improvements to both Gallio and Mb-Unit, which are now incorporated into amplify.

Labels: , , , , , , , , ,

Amplify-Fusion, JavaScript libraries compatibility layer

As one might start guessing, I tend to jump around languages, projects, and clients (web/windows client not people).  After writing custom code for , , , , , it becomes a pain to remember which library has what and to port work you've previously done into another library.  Its one thing if it porting code from one language to another, but to have port code cause of the library/framework.... its a pain that isn't needed. 

Granted the downside of writing a compatibility layer is extra code that could be duplicated else where or writing a smaller set of routines that are less in what other full blown libraries. However most people have broadband these days and the browsers have this cool thing called caching. Not to mention YUI has a great compressor and there are ways to include multiple files on the server rather than on the browser. 

So I've begun to embark on a long journey of making JavaScript widgets build on a compatibility layer of different libraries. The layer it self will take some time, testing, and constant refinement while trying to keep the layer small.  However I believe this is needed, esp as a consultant that works on various projects and everyone has their favorite library to use... 

you can find the beginnings of the code at http://code.google.com/p/amplify-fusion/.

Labels: , , ,

Amplify's WCF Twitter API Client Library v0.2

After some playing around with WCF and Flickr, I decided to move everything internally for the twitter library to use WCF with it's ServiceContract.  It was more of a pain that initially thought it would be. WCF is amazingly customizable but still has a couple of downfalls thanks to REST and people not writing their API for all technologies. 

The biggest issue is that Twitter throws an Http 403 unknown exception when you call a page and something is incorrect in the url.  Well with WCF, it throws a System.ServiceModel.Security.MessageSecurityException, due to the url returning a status code other than 200, and it wraps the inner exceptions inside of that.

I'm sure there is a better way to get around this, but each proxy call is now wrapped by a try/catch in the client class methods in order to check for the MessageSecurityException, then it checks the inner exception and determines if twitter sent back a response error message. If it does the library now throws a twitter exception with error information, otherwise you would only see the WCF exception that would mask the real issue. 

Also I renamed the "Service" classes to "Client" seeing that is the proper term for them.  The tests are now updated as well to reflect the changes.  The tests are a good way of seeing of how to use the library. Last but not least, methods now return arrays instead of lists in order to be more REST friendly.

using Amplify.Twitter;
using System.Security;

// ... stuff

public void Test() 
{
	try {
		string temp = "password";
	
		Twitter.SetCredentials("Username", temp);

		StatusClient client = Twitter.CreateStatusClient();
 		// or StatusClient client = new StatusClient("Username", temp);

        	Status[] tweets = service.GetUserTimeline();
	} catch (TwitterException ex) {
		Log.Write(ex.ToString()); // write the twitter rest error. 
	}

}

Labels: , , , , , , , ,

Pursuit of Rails like Active Record for C#

After trying , , php's code igniter framework, php's cake framework; I'm realizing how much of rails really depends on the inner workings of ruby itself to do what it is able to do.  I've looked and poked around Castle's Active Record and it does some heavy lifting, but it still seems to deviate too much from rails's version of active record.  One of the key things of porting a concept, is to keep it as close as possible so that developers can rely more on the same convention without having to relearn the concept in a different domain specific language.  Plus, I cringe a little when it leans too much on using .

It goes back to the whole "Don't make me think principle", that developers often to have to keep in mind when developing for an end user.  At first, I was thinking about creating a port would be simpler using linq with either "linq to sql" or the currently released "ado.net entity framework". After investigating, it would take a ton of invested time to either write a code generator for visual studio that would changed the way the pocos (plain old c# objects) are generated in order in corporate the changes. Also not to mention that these frameworks heavily rely on a repository pattern, that would probably cause too much pain to change for just one developer. 

Square one?  Well close enough. C# and ruby have different strengths and weaknesses. However with enough thought and using C#3.0, I think its completely possible to get something that closely resembles rails enough to give anyone who has worked with rails, something that would be familiar if they needed to work on a project in .Net. 

Labels: , , , , ,

Simplicity

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.

Labels: ,