Friday, November 25, 2011

IOC for objects loaded from orm

I like the idea of coding a Rich domain model, and then applying services to the model. Recently I was trying to get just a little closer to a rich domain, by resolving domain object dependencies during their creation via the ORM. I did find nhibernate supports this style, but alas I am currently constrained to use EF4.1 - code first.

The EF4.1 doco is.... Well there isn't any as best I can tell. For EF4 code first I've relied on blog entries, and perusing the API in object browser. In my quest for rich domain, I found no extension point in EF where I could manage entity proxy creation (pre or post load). I tried finding an override in the db context, no luck. I had some hopes there would be extensibility in te object tracker.. Nup :(.

So in the end I opted to wrap the EF model inside an IOC context aware class (spring.net), that way I coud at least get a post orm load IOC approach.
I've used a simple convention; when the ORM loads an entity, the entity full class name is used as a key in the IOC container. If it's found, the IOC is called, to resolve dependancies on the orm created object.

This approach is all I currently have, with ef4.1.
It works fine, for very simple situations, but since I've intercepted out side of the orm, I only get a shot at resolving dependencies on a top-level entity, not on any child objects that the ORMloads, which kind of makes the whole approach invalid, since I want my ORM to load a more complex entity model than just a set of top-level entities .

Wednesday, November 16, 2011

Add implied interface to a class.

Often... Well often enough, I need to use a .net framework class to implement a method. I almost always find that I want to use an interface on my class, so I can unit test it, and that the framework class provides no interface. This leads to me needing to define a interface, and implement it with a quick decorator around the framework class. Recently I was doing this with the Ping class when I decided to invest a little time looking for a better answer.

My first attempt was to use spring.net mix-ins, or introductions in AOP terms. That kinda worked, but since mixing require a class with the interface implementation, I still needed to write the decorator... not a whole lot better.

After more googling, turns out what I wanted is called duck-typing (who knew). And as with other problems, once you get the term, the googling is easy. I found a few different libraries that could help, I settled on impromptu.

It did take me a while to work out a good way of integrating with spring.net, i've used spring.net a fair bit, but haven't done a lot of extension work to date. Finally I settled on a custom factory object, it requires the target objec rand target interface, using that, it produces a ready to go decorator.
/emote "<-- nods and files away a new tool for the toolbox"

A quick sample class:
using System;
using ImpromptuInterface;
using Spring.Objects.Factory.Config;
namespace derek.kowald.BaseWebApp.Core.Extensions.Spring
{
/// <summary>
/// Custom <a href='http://www.springframework.net/'>spring.net</a>
/// factory for creating an object that implements
/// a specified interface, using a target object (<a href='http://en.wikipedia.org/wiki/Duck_typing'>duck-typing</a>).
/// </summary>
/// <remarks>
/// Leverages Impromptu for the heavy lifting, see
/// <a href="http://code.google.com/p/impromptu-interface/">http://code.google.com/p/impromptu-interface/</a>
/// Usefull for putting an interface onto a non-interface class, as found in many
/// .NET framework classes.
/// </remarks>
/// <example>
/// var raw = new MyObject();
/// var factory = new SpringDuck()
/// {
/// TargetInterface = typeof(IOther),
/// TargetObject = raw
/// };
/// factory.AfterPropertiesSet();
/// IOther wrapped = (IOther)factory.GetObject();
/// </example>
public class SpringDuck : AbstractFactoryObject
{
#region Properties
/// <summary>
/// Gets or sets the target <see cref="System.Type"/> interface.
/// </summary>
public Type TargetInterface { get; set; }
/// <summary>
/// Gets or sets the target object instance to delegate interface calls to.
/// </summary>
public object TargetObject { get; set; }
/// <summary>
/// Gets the factory returns a 'type'. This is defined by <see cref="TargetInterface"/>.
/// </summary>
public override Type ObjectType
{
get { return TargetInterface; }
}
#endregion
#region Impl
/// <summary>
/// Post set-up checks the factory is configured.
/// </summary>
public override void AfterPropertiesSet()
{
if (TargetInterface == null)
{
throw new ArgumentException("The TargetType must be provided.", "TargetType");
}
if (TargetObject == null)
{
throw new ArgumentException("The TargetObject msut be provided.", "TargetObject");
}
if (!TargetInterface.IsInterface)
{
throw new ArgumentException("The TargetType must be an interface.", "TargetType");
}
base.AfterPropertiesSet();
}
/// <summary>
/// Creates a dynamic object with the <see cref="TargetInterface"/>, using
/// <see cref="TargetObject"/> to implement the interface.
/// </summary>
protected override object CreateInstance()
{
return Impromptu.DynamicActLike(TargetObject, TargetInterface);
}
#endregion
}
}
view raw SpringDuck.cs hosted with ❤ by GitHub

Thursday, November 10, 2011

Multiple submit buttons with MVC 3.

I recently needed to create a MVC (MVC3) view with multiple submit buttons.
A quick look around with Google and I found a couple of approaches, but I thought to myself, there must be a cleaner way.

Up till now I've been using the simple approach of creating a controller action where the method takes an extra parameter to describe which action to take like:

Controller:
public class MyController
{
public ViewResult Index() { return View();}

public ViewResult DoSomething(string action, string someData)
{
if(action == "Action1") {}
else if(action == "Action2") {}
else {/*unknown action.*/ }
}
}

xhtml:
<form action="My/DoSomething>
<input name="someData"/>

<input type='submit' name='action' value='Action1' />
<input type='submit' name='action' value='Action2' />
</form>

What I wanted was to be able to define my Controller to have multiple Actions, one for each submit action on a Form, like this:

public class MyController
{
public ViewResult Index() {return View();}

public ViewResult Action1(string someData) {return View();}
public ViewResult Action2(string someData) {return View();}
}

But alas, with MVC I couldn't construct a Route that would do this; MVC routing always uses the Forms action attribute to decide which Controller method to call.

In the end the answer wasn't that hard. I just created a smarter IRouteHander, and applied it to the MVC default route.
The HTML for the form looks almost the same, though I remove the Action from the Form's action attribute, since the route handler will look after that.
xhtml:
<form action="My>
<input name="someData"/>

<input type='submit' name='action' value='Action1' />
<input type='submit' name='action' value='Action2' />
</form>


Now the methods on my controller don't need 'special' arguments, and the world is a better place :D
Here is the custom RouteHandler:

namespace derek.kowald.MVC
{
using System;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
/// <summary>
/// Custom route handler so a form submit button can
/// define the mvc action to take.
/// </summary>
/// <remarks>
/// Be careful to only define submit buttons with the name action.
/// </remarks>
/// <example>
/// Update your routes to use this hander:
/// routes.MapRoute("Default",
/// "{controller}/{action}/{id}",
/// new { controller = "Home", action="Index", id = UrlParameter.Optional})
/// .RouteHandler = new SubmitActionHandler();
///
/// Update your markup so sumbit button(s) have the name action:
/// &lt;input type='submit' name='action' value='MyAction' /&gt;
/// </example>
public class SubmitActionHandler : IRouteHandler
{
#region IRouteHandler Members
/// <summary>
/// If an input parameter named 'action' is provided,
/// update the RouteData action property with the form data.
/// </summary>
public IHttpHandler GetHttpHandler(RequestContext requestContext)
{
string reqAction = null;
if (requestContext.HttpContext != null &&
requestContext.HttpContext.Request != null)
{
reqAction = requestContext.HttpContext.Request["action"];
}
if (!String.IsNullOrEmpty(reqAction))
{
requestContext.RouteData.Values["action"] = reqAction;
}
return new MvcHandler(requestContext);
}
#endregion
}
}

A short list of C# coding issues.

Injecting services into entities It been bugging me for a while now that to use services in a entity can be a bit of pain. It usually starts...