Journal of a software dev

August 8, 2009

Adding Controls to a Server Control

Filed under: asp.net, c#, code example — Tags: , — Michael Cromwell @ 10:54 am

Usually looks like this:

var row = new TableRow();
var cell = new TableCell()
    {
         Height = Unit.Pixel(30)
    });
cell.Controls.Add( new Button()
    {
        Text = "Go",
        CommandName = "Go",
        ID = "btnGo"
    });
row.Controls.Add(cell);

How about this instead:

var row = new TableRow();
var cell = row.AppendControl<TableCell>(x =>
                  {
                      x.Height = Unit.Pixel(30);
                   });
cell.AppendControl<Button>(x =>
    {
        x.Text = "Go";
        x.CommandName = "Go";
        x.ID = "btnGo";
    });
 

Implemented with this:

public static ControlExtensions
{
    public static TControl AppendControl<TControl>(this TControl control, Action<tcontrol> initialization)
        where TControl : Control, new()
    {
        var controlToAppend = Activator.CreateInstance<TControl>();
        intialization(controlToAppend);
        control.Controls.Add(controlToAppend);
        return controlToAppend;
    }
} 

I think this reads better especially if you end up appending lots of child controls, thoughts or any other solutions?

April 11, 2009

RouteValueDictionary and why we need Hash Literals

Filed under: .net, c# — Tags: , — Michael Cromwell @ 12:26 pm

When working with ASP.NET MVC you will find quite a lot of code that needs key value pairs, especially for routing and providing html attributes, and in most of these places you will see a trend whereby no Dictionary type is created but instead an anonymous type is used:

routes.MapRoute(
    "Default",
    "{controller}/{action}/{id}",
    new { controller = "Home", action = "Index", id = "" }

So how can it take our anonymous type and create a dictionary from it? Well the object that does the work resides in System.Web.Routing and is called RouteValueDictionary (I think this should be called something like AnonymousTypeDictionary and placed somewhere else as it doesn’t really have anything to do with routing and is used in other sections), this object implements IDictionary<string, object> and has an overloaded constructor that takes a plain object type, it then uses reflection to grab the properties associated with the object and uses the property name as the key and the property value as the value.

So when any of the ASP.NET MVC objects want to create a key value pair they simply pass the anonymous type to the RouteValueDictionary object’s constructor:

// routeValues and htmlAttributes come in as object type.

return htmlHelper.ActionLink(linkText, actionName, null, new RouteValueDictionary(routeValues), new RouteValueDictionary(htmlAttributes));

And voila instant IDictionary<string, object>!

So if this works what’s the problem… well in IMO it’s hack to get round the issue that C# doesn’t have support for hash literals and it would seem I’m not alone, it suffers from a few problems:

  1. Because it uses anonymous types this means the parameter to the method has to be of type object, and from an API point of view that gives us nothing to go as to what needs to be passed in.
  2. It uses reflection to build the key value pairs which takes a performance hit.

For instance take Boo, we could write the following:

routes.MapRoute(
    "Default",
    "{controller}/{action}/{id}",
    { "controller" = "Home", "action" = "Index", "id" = "" }

Or by using the open compiler wizardry:

routes.MapRoute(
    "Default",
    "{controller}/{action}/{id}",
    { controller = "Home", action = "Index", id = "" }

Maybe this is asking too much from the compiler and this is as close as were going to get but that would be a shame given the problems above this approach suffers from.

January 11, 2009

Registering a mock/stub with Windsor

Filed under: Castle Windsor, TDD, c#, code example, mocking, mocks, rhino mocks, testing, tips, unit testing — Tags: , , , , — Michael Cromwell @ 1:52 pm

I have some code that uses Castle Windsor to retrieve instances this helps to manage dependencies that I don’t have to worry about, the side effect of this is that when performing unit tests against the code that needs to get an instance from Windsor I want to provide a way to inject a mock/stub object is can be accomplished with the following:

container.Register(Component.For<IFoo>()
                                        .Instance(mockFoo));

To help reduce the amount of code in my test setups I usually have this method in my Unit Testing base class

protected void RegisterDependencyAgainst<TInterface>(TInterface instance)
{
    container.Register(Component.For<TInterface>()
                                .Instance(instance));
}

Which is then called like this:

// in setup method
mockFoo = MockRepository.CreateMock<IFoo>();
RegisterDependencyAgainst<IFoo>(mockFoo);

November 28, 2008

Getting to grips with NHibernate: Stored Procedures Redux

Filed under: .net, advice, c#, code example, nhibernate, sql, tips — Michael Cromwell @ 8:23 pm

Update: Due to popular demand I have included using stored procedures for insert/update/delete

I hope this post saves someone the amount of time it took me to try and run a stored procedure using NHibernate.

Selecting from a Stored Procedure

Create Stored Procedure

The first step is to create your stored procedure, if we take a basic example:

CREATE PROCEDURE SearchStaff
	(
	@LastName VARCHAR(255) = NULL,
	@FirstName VARCHAR(255) = NULL
	)
AS
	SET NOCOUNT ON

	SELECT s.*
	FROM Staff s
	WHERE (s.LastName LIKE @LastName OR @LastName IS NULL)
	AND (s.FirstName LIKE @FirstName OR @FirstName IS NULL)
	ORDER BY FirstName, LastName

	SET NOCOUNT OFF

Note the SET NOCOUNT ON/SET NOCOUNT OFF

Create a named query

In order for NHibernate to be able to run the stored procedure, we need to create a named query, in our hbm file:

<sql-query name="StaffSearching">
	<return class="Foo.Core.Staff, Foo.Core">
	  <return-property name="Id" column="Id"/>
	  <return-property name="LastName" column="LastName"/>
	  <return-property name="FirstName" column="FirstName"/>
	  <return-property name="MiddleName" column="MiddleName"/>
	</return>
	exec SearchStaff :LastName, :FirstName
</sql-query>

In this example because the stored procedure is actually returning a staff object I set the return to the Staff class, if I was only returning something like an integer value I could use the following:

<sql-query name="TotalStaff">
    <return-scalar type="Int32" column="Count"/>
    exec StaffCount :LastName, :FirstName
</sql-query>

The name does not need to be the same name as the stored procedure.

Create the NHibernate code

// session set here

IQuery searchQuery = session.GetNamedQuery("StaffSearching")

if (!string.IsNullOrEmpty(LastName))
	searchQuery.SetString("LastName", LastName);
else
    searchQuery.SetString("LastName", null);

if (!string.IsNullOrEmpty(FirstName))
    searchQuery.SetString("FirstName", FirstName);
else
    searchQuery.SetString("FirstName", null);

IList foundStaff = searchQuery.List();

Notice that the stored procedure can deal with or without filtering, so if the fields have not been set we can simply set them to a null value and NHibernate will pass the parameters as a NULL which is what we want.It’s worth noting that the above is quite a simple example and that for the above I would not use a stored procedure and instead just use NHibernates own querying objects. The case were I used a stored procedure was for a paging routine for SQL server 2000.

Using Stored Procedure for Insert, Update & Delete

Create Stored Procedures

CREATE PROCEDURE InsertStaff
	(
	@LastName VARCHAR(255),
	@FirstName VARCHAR(255),
             @EmailAddress VARCHAR(512)
	)
AS
             INSERT INTO Staff
             (
              LastName,
              FirstName,
              EmailAddress
             )
             VALUES
             (
              @LastName,
              @FirstName,
              @Email
             )

Note: SET NOCOUNT is not set for these stored procedures

I’m not going to include the SQL for the update and delete stored procedures as I don’t think it adds any value, and is the easy part.

Update NHibernate XML Mapping

We need to tell NHibernate the SQL we want to execute for our insert/update/delete, we do this inside the class element:

<class name="MCromwell.StaffIntranet.Core.Staff, MCromwell.StaffIntranet.Core" table="Staff">
    <id name="Id" column="Id" type="Int32">
      <generator class="native" />
    </id>
    <property name="LastName" column="LastName" type="String" length="255"/>
    <property name="FirstName" column="FirstName" type="String" length="255"/>
    <property name="EmailAddress" column="EmailAddress" type="String" length="512"/>

    <sql-insert>EXEC InsertStaff ?,?,?</sql-insert>
    <sql-update>EXEC UpdateStaff ?,?,?,?</sql-update>
    <sql-delete>EXEC DeleteStaff ?</sql-delete>
</class>

Caveats

  • The last parameter will be the id for the update.
  • The ordering of the parameters is determined by NHibernate, so the best way to find out the ordering would be to view the generated SQL, bit pants but hay ho.

Your code will remain the same, so no changes needed there.

November 16, 2008

Staff Intranet Updated

Filed under: best practices, c#, code example, design pattern, oop, software design — Tags: , , , — Michael Cromwell @ 7:45 pm

I just updated the staff intranet project over on codeplex, I have now got it under source control now that they have added support for SVN :) And have also uploaded a new release of the source in case you dont have a source control client compatible.

The changes are:

  • Incorporating some of my other projects (log4net-altconf, object2object mapper) to help with the maintainability of the app.
  • Refactorings I have made to the way a staff member is saved. After gaining a better understanding of DDD principles it was quite clear that the validation around the photo upload & checking for name duplication should be separated as Specification objects to reduce the coupling in the Staff object.

Remember any feedback you can post here on my blog or on codeplex

September 6, 2008

Lightweight Object Mapper Infomercial

Filed under: .net, c# — Tags: , , , — Michael Cromwell @ 4:31 pm

Tired with writing monotonous & repetitive mapping code, wish their was an easier way to map object A to object B, well look no further, introducing the Lightweight Object to Object Mapper.

As Seen on TV

The Lightweight Object to Object Mapper is designed to make object mapping a doddle! By employing the latest techniques in convention over configuration reduced coding is guaranteed[1] and for those tricky to reach places explicit property mapping can be achieved with minimal effort and fuss.

So don’t lose out, download Lightweight Object Mapper right now and start enjoying object to object mapping, but that’s not all for a limited time period if you download the Lightweight Object to Object Mapper you will receive accompanying unit tests… so don’t delay download now!

  1. Guarantee is subject to both the mapped from & mapped to object structure

August 19, 2008

Null Object Pattern by example

I feel sorry for the Null Object pattern, while Abstract Factory Pattern, Strategy and the other patterns from the GoF book get all the attention the Null Object pattern doesn’t get a look in. This is a shame because this pattern can come in very useful, saving you many scattered ==null checks across your code, I’m going to show a real world use of Null Object pattern (and Adapter pattern as a by-product) using example logging objects:

Lets get to it, we have an ILog it looks like this:

public interface ILog
{
    void Debug(string message);
}

Ok granted I have made it a simple example at least it ain’t an ICar or IAnimal ;) how do we get hold of our ILog with an ILogFactory of course:

public interface ILogFactory
{
    ILog GetLog(Type type);
}

We can make this easier to get hold of by having a static gateway so we aren’t having to pass around an ILogFactory to every object or having to new up a ILogFactory instance everytime we want to log:

public static class Log
{
    private static logFactory;

    public static void InitializeWith(ILogFactory logfactory)
    {
	this.logFactory = logFactory;
    }

    public static ILogFactory Current(Type type)
    {
        return logFactory.GetLog(type);
    }
}

You could also leverage a IoC container here instead.

Now we want some implementations I’m a fan of log4net so I would implement the following:

public class Log4NetLogFactory
{
    public ILog GetLog(Type type)
    {
	//retrieve an adapted log4net log something like...
	log4net.ILog rawLog = log4net.LogManager.GetLogger(type);
	return new Log4NetLog(rawLog);
    }
}

With Log4NetLog looking like this:

public class Log4NetLog : ILog
{
    private log4net.ILog log;

    public Log4NetLog(log4net.ILog logToAdapt)
    {
	this.log = logToAdapt;
    }

    public void Debug(string message)
    {
	if (log.IsDebugEnabled)
	    log.Debug(message);
    }
}

Now we want to be able to log in our client code like this:

Log.Current(this.GetType()).Debug("some debug message");

The problem of course is that if we try to do this without hooking up our static Log class to an ILogFactory we get the dreaded null reference exception, this is bad! Our logging code should not throw exceptions, enter the Null Object pattern:

public static class Log
{
    private static logFactory = new NullLogFactory();

    public static void InitializeWith(ILogFactory logfactory)
    {
	if (logFactory != null)
	    this.logFactory = logFactory;
    }

    public static ILogFactory Current(Type type)
    {
        return logFactory.GetLog(type);
    }
}

We instantiate a new NullLogFactory object and assign it to the static logFactory member, we also perform a check to make sure no nulls are sent to the InitializeWith method, here is the NullLogFactory:

public class Log : ILogFactory
{
    public ILog GetLog(Type type)
    {
        return new NullLog();
    }
}

All this does is new up a NullLog object:

public class NullLog : ILog
{
    public void Debug(string message)
    {
    }
}

The NullLog does nothing whatsoever apart from prevent us from receiving null reference exceptions, the neat thing about this though is that we could potentially capture attempts to call methods the NullLog and perform some sort of internal debugging:

public class NullLog : ILog
{
    public void Debug(string message)
    {
        if (Config.IsInternalDebugEnabled)
            Debug.Write("'{0}' sent to NullLog", message);
    }
}

That way users of the logging objects can be notified if logging has taken place but a log factory has not been hooked up.

June 27, 2008

New Staff Intranet Release

I have found enough spare time to put up a new release of the staff intranet project, for those who are not aware of this project it is a demonstration of using best practices, principles & patterns in a real world web application so if your looking for pointers or some code to use for your own applications go give it a look on codeplex.

In this newest version I have added AOP support to cut down on cross cutting code and also the ability to delete staff members from the GridView, most of the time spent was fighting against the asp.net controls (suprise, surprise) such as the GridView and the ObjectDataSource, I’m not sure what the guy(s) who created the ObjectDataSource object was smoking at the time but it must have been stronger than just tobacco :-)

My next release I want to demonstrate adding some service support showing how we can re-use existing code so they become little more than a remote facade (in theory!).

June 12, 2008

Enforcing Conventions

Filed under: .net, advice, aop, c#, code example, continuous integration, testing, tips, unit testing — Tags: , , , , — Michael Cromwell @ 7:44 pm

In my last post I demonstrated adding AOP to cut down on cross cutting code, and at the end mentioned that it would be nice to enforce a convention throughout the system, the example being each public method in the task layer being decorated with a certain attribute.

I was unsure about how to do this until recently seeing a post by Ayende http://www.ayende.com/Blog/archive/2008/05/05/Actively-enforce-your-conventions.aspx in it he references an article by Glenn Block whereby both of them came up with a unit test called PrismShouldNotReferenceUnity in the test they use reflection to check that there are indeed no references from the Prism assembly to the Unity assembly.

This is a great idea! You now have a repeatable test that can be run to make sure the conventions for your system are met, so armed with this technique I created the following test:

[Test]
public void task_class_methods_should_be_marked_with_wrap_exception_attributes()
{
    try
    {
        Assembly asm = Assembly.LoadFrom( "MCromwell.StaffIntranet.Task.dll" );
        var wrapExceptionType = asm.GetType( "MCromwell.StaffIntranet.Task.Infrastructure.WrapExceptionWithAttribute" );
        Assert.IsNotNull(wrapExceptionType);

        foreach (Type current in asm.GetTypes())
        {
            if (current.FullName.StartsWith( "MCromwell.StaffIntranet.Task.Tasks." ) && (!current.IsInterface) && (!current.IsAbstract))
            {
                foreach (var method in current.GetMethods())
                {
                    if ((method.IsPublic) && (method.DeclaringType.Name != "Object"))
                    {
                        if (method.GetCustomAttributes(wrapExceptionType, false).Length <= 0)
                            Assert.Fail("no wrap exception attribute found on type '{0}', method '{1}'", current.FullName,method.Name);
                    }
                }
             }
        }
    }
    catch (ReflectionTypeLoadException rex)
    {
        foreach (var current in rex.LoaderExceptions)
            Console.WriteLine(current.ToString());
        throw;
    }
    catch (Exception ex)
    {
        Console.Error.Write(ex.Message);
        throw;
    }
}

In here you can see by leveraging reflection I can browse all the public methods for my task layer classes and make sure they do indeed have a WrapExceptionWithAttribute the other cool thing is that by doing it this way I can freely add new classes and they will need to comply with the conventions set out or the testing will fail, cool eh!

One thing to point out is that if you start increasing the number of conventions and want a better way to control and report on, you probably want to look into something like FXCop or NDepend’s CQL.

June 10, 2008

Adding AOP to Staff Intranet

Because I’m a stickler for good code I put exception handling into my task layer and wrap any exception that may be raised from the data access layer into an appropriate exception for the task layer and also log the exception, because of this I end up having lots of unit test code that looks similar to make sure I’m enforcing this rule:

[Test]
public void Should_log_exception_if_exception_is_raised_when_deleting_session()
{
    Guid id = Guid.Empty;
    IAdministrationRepository mockRepository = CreateMock<IAdministrationRepository>();

    IServiceResolver mockResolver = CreateMock<IServiceResolver>();
    ILog mockLog = CreateMock<ILog>();
    Exception mockException = new Exception( "mock ex" );

    using (Record)
    {
        SetupResult.For(mockResolver.Resolve<ILog>())
                   .Return(mockLog);
        SetupResult.For(mockRepository.FindLoginSessionBy(id))
                   .IgnoreArguments()
                   .Return(new LoginSession(id));
        mockRepository.Delete(null);
        LastCall.IgnoreArguments()
                .Throw(mockException);
        mockLog.Error(mockException);
    }

    using (PlayBack)
    {
        try
        {
            IoC.InitializeWith(mockResolver);
            IAuthenticationTask sut = createSUT(mockRepository);
            sut.InvalidateSessionFor(id);
        }
        catch { }
    }
}

And to fulfill this I then end up with cross cutting code to meet the test behaviour:

try
{
    //... work here
}
catch (Exception thrownException)
{
    Log(thrownException);
    throw new ProblemSavingStaffMemberException(thrownException);
}

To try and cut down on this cross cutting code and to keep the tasks more lean I did some investigation into some AOP strategies.

My first reaction was… I’m using Castle Windsor so can I utilize it’s built in AOP capabilities after changing some code and adding an interceptor I quickly found out this won’t be possible as it doesn’t support out or ref parameters and due to some of my task layer method using out parameters to pass back a notification object this choice was gone!

Next up I had a look at PostSharp the difference between them being that PostSharp adds code in after compilation whereas Windsor dynamically creates proxies at runtime. After looking at some examples I had an idea as to how to implement it so after installing PostSharp I created my object that will inject itself into other objects:

[Serializable]
[AttributeUsage(AttributeTargets.All)]
public class TaskExceptionHandlerAttribute : OnMethodBoundaryAspect
{
    public override void OnException(MethodExecutionEventArgs eventArgs)
    {
        Exception thrownException = eventArgs.Exception;
        LogException(thrownException);
        WrapExceptionWithAttribute wrapExceptionAttribute = RetrieveWrappingExceptionAttribute(eventArgs.Method);
        if (wrapExceptionAttribute != null)
        {
            Type exceptionToWrapWith = wrapExceptionAttribute.WrapExceptionType;
            Exception exceptionToThrow = (Exception)Activator.CreateInstance(exceptionToWrapWith, thrownException);
            if (exceptionToThrow != null)
                throw exceptionToThrow;
        }
        throw new TaskLayerException(thrownException);
    }

    private static WrapExceptionWithAttribute RetrieveWrappingExceptionAttribute(MethodBase method)
    {
        WrapExceptionWithAttribute wrapExceptionAttribute =
        method.GetFirstCustomAttribute<WrapExceptionWithAttribute>(typeof(WrapExceptionWithAttribute),false);
        return wrapExceptionAttribute;
    }

    private static void LogException(Exception thrownException)
    {
        ILog log = IoC.Resolve<ILog>();
        log.Error(thrownException);
    }
}

In order to not have to place this object as an attribute on all the different task classes I can use the assembly attribute and give it a target using a name plus a wildcard:

[assembly: TaskExceptionHandler(AttributeTargetTypes="MCromwell.StaffIntranet.Task.Tasks.*")]

And that’s it my methods are now injected with the PostSharp code after compilation to handle exceptions and at which point it will call my custom code very cool!

One thing you may have noticed is the use of another attribute that can be decorated on the task methods WrapExceptionWithAttribute this attribute takes a Type in it’s constructor this Type is the exception that should wrap the thrown exception ideally we would like this attribute to be placed on all public task class methods so that we raise applicable exceptions depending on the task be performed although how do we enforce this convention?…

In my next post I will be demonstrating a technique that allows to enforce these types of conventions we want for our systems.

Older Posts »

Blog at WordPress.com.