Skip to main content

Posts

Considerations for Multi-Client Applications

Often when dealing with applications/systems that serve multiple clients, we encounter a situation where Clients share some core functionality and algorithms Clients have custom logic that extends the core functionality Clients have customized data structures that extend core data structures The key to making this work in a maintainable way (that is, without infusing the code with crazy branching statements or writing the whole application in dynamic SQL) is maintaining a distinct separation between core and client. Here I present components from a simple, hypothetical application that demonstrates such a separation. The application is meant to evaluate whether or not a client should acquire a player for fantasy football. It contains some core functionality for doing the evaluation (it doesn't pick up a player who has never scored a point) and a core data structure that represents a player. There are two clients who extend this core functionality: me and a stupid ...

Duck Typing with Anonymous Types - Part 3

Continuing my short series , it's time to add some polish to what we have so far. Overload Resolution At first I thought overload resolution was going to be a huge pain, but really the compiler does everything for us. As long as we have assigned an implementation with exactly matching parameters for the method that the compiler calls, we're good to go. The necessary modifications to the interceptor fit into a small reflection utility method. private Delegate GetMethod(IInvocation invocation) { var methodProperty = anonymous.GetPropertyValue(invocation.Method.Name); if (methodProperty is Delegate) { return methodProperty as Delegate; } var overloads = methodProperty as Delegate[]; return overloads.Where(m => m.Method.SignatureMatches(invocation.Method)).First(); } internal static bool SignatureMatches(this MethodInfo method, MethodInfo other) { var theseParameters = method.GetParameters(); var thoseParameters = other.GetParameters(); ...

Duck Typing with Anonymous Types - Part 2

Previously I looked at forwarding property calls of an interface to those of an anonymous type instance. Now I'd like to see if we can forward method calls as well. But how? We can't create an anonymous type instance with methods, and we can't assign assign anonymous methods as properties. This doesn't work: var duck = new { Color = "white", Quack = () => "Quack!" }; but this does: [Test] public void CanInvokeMethod() { var duck = new { Color = "white", Quack = (Func<string>)(() => "Quack!") }; } Let's modify our interceptor once again, this time to retrieve a delegate property named the same as the invoked method and invoke it. internal class DuckTypingInterceptor : IInterceptor { [... snip ...] public void Intercept(IInvocation invocation) { [... snip ...] if (invocation.IsMethodCall()) { var method = GetMethod(invocation.Metho...

Duck Typing with Anonymous Types

If you can create an anonymous method and an anonymous type , why not an 'anonymous class'? Wouldn't it be nice to be able to plug properties and methods into and object and then consume that object like any other class or interface ? What we're talking about is essentially duck typing (with strongly-typed ducks). There are examples all over of how to do this, especially with Castle Dynamic Proxy. This is my implementation of the same. First let's look at a test: public interface IDuck { string Color { get; } Direction Fly(); Direction Fly(Direction direction); string Quack(); } [Test] public void CanStubColorProperty() { var rubberDuck = new { Color = "yellow" }; var typedRubberDuck = rubberDuck.As<IDuck>(); Assert.That(typedRubberDuck.Color == "yellow"); } That As<IDuck> part is an extension method that does nothing right now, so this test will fail. What we want that extensions method to do is to re...

Mercurial / hg-git / Github Setup Link

This is just so I don't forget or lose it: this post has probably the best guide to getting TortoiseHg set up as a github client on Windows: james mckay dot net - TortoiseHg as a github client on Windows Apparently I don't know how to use Google, because I always struggle to find this. UPDATE: Be careful not to wrap the hggit extension path in quotes in the mercurial config file *even if the path has a directory with a space in it*. I was setting mine like this: [extensions] hggit = "C:\ABC DEF\hg-git\hggit" but that was causing this error: *** failed to import extension hggit from "C:\ABC DEF\hg-git\hggit": [Errno 22] Invalid argument Removing the quotes fixed the problem: [extensions] hggit = C:\ABC DEF\hg-git\hggit

Serializing Anonymous Methods

I’m taking some time off from not blogging to do a little blogging. I hope this doesn’t inconvenience absolutely nobody. I was doing some [binary] serialization work recently when I came across a problem – I wanted to serialize objects with delegate fields that were populated with anonymous methods at runtime. To wit, I had types like this: public delegate void MakeMove(); public class AdrianPeterson { public int GameOneYards { get; set; } public Football Ball { get; set; } public MakeMove Move { get; set; } } Populated like this: var explicitDirections = new List<string> { "left", "right", "left" }; var ap = new AdrianPeterson(); var apName = ap.GetType().Name; ap.GameOneYards = 87; ap.Move = () => Moves.Weave(apName, explicitDirections); So, I pop a [ Serializable ] on AdrianPeterson (and Football ), and I’m set, right? Wrong. Wrong like getting away from running AP in the second half when the only receiving threat you have is bei...

Micro Fluency

I’ve been having a lot of conversations at work lately about how comments are a code smell , and if you’re not writing self-documenting code , ur doin it rong . Then I found myself in a position I’ve been in quite a few times… The general description is this: I have a method that takes two parameters. The action the method performs is best written in English in the form “{SomethingTheObjectDoesWith} {parameter1} {On/With/For/SomeOtherPreposition} {parameter2}”. The only way to name the method is “ SomethingTheObjectDoesOn/With/For(parameter1, parameter2)” . It seems like I run into this situation too often. The API for all of the concerned code doesn’t necessitate building out a huge fluent interface for readability, but it would be nice to have things read just a little better in this case. An example is certainly in order. I have an ASP.NET server control that activates a certain index on an associated MultiView . In order to let client code know whether or not it activates an in...