2007-03-20 - Architecture Camp 2007

Well as the more observant reader of Alex Jame's Blogmight have noticed, I'm talking at the the Architect Camp 2007 this year... which should be...interesting - I haven't done any public speaking for a while now, but Alex James assures me I'll be fine ... be it on his head! ;o) ...

So I'm planning to talk about IoC (Inversion of Control) - one of my little pet loves... Some of the subjects I'm considering include:

  • Coupling
    • How do we couple (Message, data, content etc.)
    • Metrics for the architect (Instability vs. Abstractness etc.)


  • Dependency Injection
    • Constructor dependencies
    • Parameter dependencies
    • Law of Demeter


  • Inversion of Control
    • Why bother?
      • Added flexibility and opportunity
      • Lowering the cost of change


    • ServiceLocators
      • Why they suck


    • Inversion of control containers
      • What's available (Castle, Spring, StructureMap etc.)
      • Autowiring
      • Services
      • Lifestyle vs Lifecycle
      • Configuration
      • AOP
      • Patterns
        • Decorators
        • Facilities
        • Arrays (simple contributor patterns etc.)








But that's only a small brain dump... we will see what actually gets in there.

For anyone who's thinking of attending this event, anything in particular you would like to have covered in a little more depth... or have you had any exposure to IoC at all?

Read More

Fluent mocking...

Well first off... where has this month gone??... it's been 2 weeks since I last blogged... I thought it was only a week!

At any rate, one of the things I've been working on lately is mocking out COM interfaces (using RhinoMocks of course) ... and I have to admit that my eyes start crossing after a while, at about the point where the mock repositories setup code begins dominating the test case... which happens all too often... here's a smaller example of what I'm talking about:

MockRepository repository = new MockRepository();

TaggedValue oneTaggedValue = repository.DynamicMock();
Expect.Call(oneTaggedValue.Value = "").Constraints(Is.Equal("ExpectedValue"));
Expect.Call(textAlignTaggedValue.Update()).Return(true);

TaggedValue anotherTaggedValue = repository.DynamicMock();
Expect.Call(anotherTaggedValue.Value = "").Constraints(Is.Equal("AnotherExpectedValue"));
Expect.Call(textAlignTaggedValue.Update()).Return(true);

Collection taggedValuesCollection = repository.DynamicMock();

Expect.Call(taggedValuesCollection.GetByName("")).Constraints(Is.Equal("OneTaggedValue"))
.Return(oneTaggedValue).Repeat.Any();

Expect.Call(taggedValuesCollection.GetByName("")).Constraints(Is.Equal("AnotherTaggedValue"))
.Return(anotherTaggedValue).Repeat.Any();

Element destinationElement = repository.DynamicMock();
Expect.Call(destinationElement.TaggedValues).Return(taggedValuesCollection).Repeat.Any();

repository.ReplayAll();

So in this case we have an "Element", which has a collection of "TaggedValues", and we have two tagged values "OneTaggedValue" and "AnotherTaggedValue", and for each we are updating their values, and then invoking "Update()" on them to flush the changes...

To help solidify that, here's an example of what we're expecting to happen to our element (Element, Collection and TaggedValue are all interfaces from a COM interop assembly, in case you were wondering):

    Element element;

...

TaggedValue oneTaggedValue = (TaggedValue)element.TaggedValues.GetByName("OneTaggedValue");
oneTaggedValue.Value = "ExpectedValue";
oneTaggedValue.Update();
TaggedValue anotherTaggedValue = (TaggedValue)element.TaggedValues.GetByName("AnotherTaggedValue");
anotherTaggedValue.Value = "AnotherExpectedValue";
anotherTaggedValue.Update();

Now normally in this case I take unit tests once I've got "green" and refactor the mocking code out a bit... so in the above case I'd probably end up with something like:

MockRepository repository = new MockRepository();

Collection taggedValuesCollection = repository.DynamicMock();
AddTaggedValueSetter(repository, taggedValuesCollection, "OneTaggedValue", "ExpectedValue");
AddTaggedValueSetter(repository, taggedValuesCollection, "AnotherTaggedValue", "AnotherExpectedValue");

Element destinationElement = repository.DynamicMock();
Expect.Call(destinationElement.TaggedValues).Return(taggedValuesCollection).Repeat.Any();

repository.ReplayAll();

Which works... generally quite well... but lately I've been moving away from that approach and instead have been refactoring the setup code into a fluent interface... which I've found to be a lot easier to maintain and extend (and tends to be a little more re-usable across multiple test fixtures...) So for example, this is what the setup code for the above mock element is now:

MockRepository repository = new MockRepository();

Element element =
Mock
.Element()
.HasTaggedValue("OneTaggedValue").ExpectSetValue("ExpectedValue")
.HasTaggedValue("AnotherTaggedValue").ExpectSetValue("AnotherExpectedValue")
.Complete(repository);

repository.ReplayAll();

I'm just skimming the surface of what I've been doing, but it might be food for thought for anyone working on similar projects... anyone else doing similar things?

Read More

Expression trees are great...

Have you ever wanted to be able to do something like this in
C#?



string propertyName = GetName(MyClass.MyProperty);



Well I have, in fact I've wanted the ability to do this since
Version 1 of the .Net Framework, and now with C# 3.0 we finally
can!



First off, check out the original blog post here -
Symbols in C# 3.0
by Jafar Husain - it's a
clever (and once I thought about, plainly obvious) use of extension
methods and expression trees.


public static class SymbolExtensions
{
public static string GetPropertySymbol(this T obj, Expression<>> expr)
{
return ((System.Linq.Expressions.MemberExpression) (((System.Linq.Expressions.LambdaExpression)(expr)).Body)).Member.Name;
}
}


Usage requires a lambda, but that's not to painful, here's example
usage:


MyClass o;
//...
string propertyName = this.GetPropertySymbol(o => o.MyProperty)


The beauty of this is that refactoring is entirely painless, you
don't need to spend time reviewing all the optional string
replacements that resharper may have found in case you haven't
mirrored a property or method name change correctly... it also
looks like it could offer some nice usability improvements to some
unit testing scenarios (nothing worse then unit tests that don't
seamlessly refactor with your code).



I wonder what other ideas are floating around for expression trees
at the moment (outside of the obvious querying concepts) ?
Read More

Event orders...

Dumping events

I'm often surprised (or is it dismayed) when questions pop up
in news groups surrounding things like event orders for winforms or
webforms applications... this isn't rocket science... we're given
all the tools to make this easy to figure out!



Lets do a winforms 2.0 app as an example... first off, the earliest
point at which can easily get involved is the constructor... 
lets have a look:


public partial class Form1 : Form
{
public Form1()
{
AttachToAllEvents();
InitializeComponent();
}


So I'm going to attach to all the events before the forms
components are initialized... now lets have a look at the
"AttachToAllEvents" method.


private void AttachToAllEvents()
{
Type type = GetType();

foreach (EventInfo info in type.GetEvents())
{
string eventName = info.Name;

EventHandlerWrapper wrapper = new EventHandlerWrapper(new EventHandler(
delegate
{
Console.WriteLine("{0}: EventName: {1}, IsVisible: {2}, IsHandleCreated: {3}, HasChildren: {4}, IsDisposed: {5}",
DateTime.Now, eventName, this.Visible, this.IsHandleCreated, this.HasChildren,
this.IsDisposed);
}));

wrapper.Attach(this, info);
}
}



Only magic there is we're using a class called
"EventHandlerWrapper" - what's that... well, it's used to
create a strongly typed delegate for attaching to an event.



The reason we need this at all is because
EventInfo.AddEventHandler(...) is fussy about the kind of
delegate you supply, so if you pass in an "EventHandler" for
a "CancelEventHandler" event, it'll throw an exception
complaining about it's inability to cast between them... there
might be an easier way to do this, but I haven't come across it so
far.


public class EventHandlerWrapper
{
private EventHandler _handler;
private static readonly MethodInfo _methodInfo;

static EventHandlerWrapper()
{
_methodInfo = typeof(EventHandlerWrapper).GetMethod("InvokeHandler", BindingFlags.NonPublic | BindingFlags.Instance);
}

public EventHandlerWrapper(EventHandler handler)
{
if (handler == null) throw new ArgumentNullException("handler");
_handler = handler;
}

public void Attach(object target, EventInfo info)
{
Delegate wrappedHandler = Delegate.CreateDelegate(info.EventHandlerType, this, _methodInfo);
info.AddEventHandler(target, wrappedHandler);
}

private void InvokeHandler(object sender, EventArgs args)
{
_handler(sender, args);
}
}



With a little brain power I'm sure I could've done this without the
separate wrapper class, but this is probably a little easier to
read at any rate.


Results..?

So.. onto the results - once we run the code and see exactly
what order events are happening in, we can then make a pretty table
that may not render in most browsers because I cut 'n pasted it
from Excel 2007 ;o)



cellpadding="0" cellspacing="0" width="563">

height="20" width="162"> EventName

width="81">  IsVisible

width="128">  IsHandleCreated

width="100">  HasChildren

width="92">  IsDisposed


height="20"> Resize
 False
 False
 False
 False


height="20"> SizeChanged
 False
 False
 False
 False


height="20"> ClientSizeChanged
 False
 False
 False
 False


height="20"> ClientSizeChanged
 False
 False
 False
 False


height="20"> ControlAdded
 False
 False
 True
 False


height="20"> ControlAdded
 False
 False
 True
 False


height="20"> StyleChanged
 False
 False
 True
 False


height="20"> TextChanged
 False
 False
 True
 False


height="20"> Move
 False
 True
 True
 False


height="20"> LocationChanged
 False
 True
 True
 False


height="20"> HandleCreated
 False
 True
 True
 False


height="20"> Invalidated
 False
 True
 True
 False


height="20"> StyleChanged
 False
 True
 True
 False


height="20"> ChangeUICues
 True
 True
 True
 False


height="20"> Invalidated
 True
 True
 True
 False


height="20"> BindingContextChanged
 True
 True
 True
 False


height="20"> Load
 True
 True
 True
 False


height="20"> Layout
 True
 True
 True
 False


height="20"> VisibleChanged
 True
 True
 True
 False


height="20"> Activated
 True
 True
 True
 False


height="20"> Shown
 True
 True
 True
 False


height="20"> Paint
 True
 True
 True
 False


height="20"> Paint
 True
 True
 True
 False


height="20"> Paint
 True
 True
 True
 False


height="20"> MouseCaptureChanged
 True
 True
 True
 False


height="20"> Closing
 True
 True
 True
 False


height="20"> FormClosing
 True
 True
 True
 False


height="20"> Closed
 True
 True
 True
 False


height="20"> FormClosed
 True
 True
 True
 False


height="20"> Deactivate
 True
 True
 True
 False


height="20"> HandleDestroyed
 True
 True
 True
 False


height="20"> Disposed
 False
 False
 False
 False





The main thing to keep in mind when doing something like this is to
avoid making assumptions - we may not be the first or last to
attach to the events (depending on the complexity of the form) -
and events can trigger other events... which could explain the
ordering of some of this data i.e. changes in visibility and handle
creation... if anything we are viewing the order of consequences,
as opposed to the true order in which the events are invoked (to
get that we'd need to override all the OnXXXX methods of the form
class... which would be a good job for dynamic
proxy
:)
Read More

Thankyou mr tortoise...

I've been using tortoise SVN for a couple of years now... but I'd never seen this dialog before when renaming files with similar name patterns... probably old news to some people, but it pleased me no end, very helpful!


It's these kinds of features that I like about an explorer based SCM client... I find IDE integrated source control just bugs me now days (like Team System which I use for codeplex).

Read More