Search And Destroy

Look out honey, ’cause I’m using technology!

Archive for the ‘C# Musings’ Category

NHibernate Integration Testing Helpers

Posted by kilfour on September 8, 2011

What I want to test :

[Test]
public void MapperShouldNotCauseExtraQueries()
{
    using(0.Queries())
    {
        Mapper.Map(entityResultFromQuery);
    }
}

The plumbing :
public class QuerySpy : IDisposable
{
    private readonly int expectedNumber;
    private readonly NHibernateSqlLogSpy spy;

    public QuerySpy(int expectedNumber)
    {
        this.expectedNumber = expectedNumber;
        spy = new NHibernateSqlLogSpy();
    }

    public void Dispose()
    {
        Assert.AreEqual(expectedNumber, spy.Appender.GetEvents().Count());
    }
}

public static class NumberOfQueriesUsedExtension
{
    public static QuerySpy Queries(this int expectedNumber)
    {
        return new QuerySpy(expectedNumber);
    }
}

public class NHibernateSqlLogSpy : LogSpy
{
    public NHibernateSqlLogSpy() : base("NHibernate.SQL") { }
}

public class LogSpy : IDisposable
{
    static LogSpy()
    {
        XmlConfigurator.Configure();
    }

    private readonly MemoryAppender appender;
    private readonly Logger logger;
    private readonly Level prevLogLevel;

    public LogSpy(string loggerName)
    {
        logger = LogManager.GetLogger(loggerName) as Logger;
        if (logger == null)
            throw new NullReferenceException();
        prevLogLevel = logger.Level;
        logger.Level = Level.Debug;
        appender = new MemoryAppender();
        logger.AddAppender(appender);
    }

    public MemoryAppender Appender { get { return appender; } }

    public virtual void Dispose()
    {
        logger.Level = prevLogLevel;
        logger.RemoveAppender(appender);
    }
}

Posted in C# Musings, NHibernate | Leave a Comment »

Test That Mapping, … Once and For All

Posted by kilfour on August 10, 2011

I’m sure you’re all aware of how mapping business entities to DTO’s is quite a menial task and that there are several strategies to deal with that.

I employ more than one of those strategies.

But one that I use quite a bit, mainly because of speed of development, is the nhibernate/automapper combo.

Once the handler, repositories, queryobjects et all (or whatever infrastructure you use to get the data to your view) is in place, all one needs to do is, add a rightly named property to the dto and magically it gets populated with the desired value.

You don’t even have to adapt any test thanks to the AssertConfigurationIsValid method of AutoMapper.

However, ever since I first started using this way of working, two things about it all have been bothering me :
1. The need for a ‘Registry’ type class (or a static method, or whatever), where one registers all the mappings.
F.i. :

public static class Boot
{
	public static void Strap()
	{
		CreateMap<GetBetalingsAanvraagByIdentificatieResponse.BetalingsAanvraagDto, BetalingsaanvraagErelonenViewModel>()
			.ForMember(dest => dest.TotaalBedrag, options => options.Ignore());
		CreateMap<GetBetalingsAanvraagByIdentificatieResponse.BetalingsAanvraagLijnDto, BetalingsaanvraagLijnViewModel>()
			.ForMember(dest => dest.Totaal, options => options.Ignore());
		CreateMap<GetBetalingsAanvraagByIdentificatieResponse.StavingsDocumentDto, BetalingsaanvraagDocumentViewModel>();

		CreateMap<GetBetalingsAanvraagByIdentificatieResponse.BetalingsAanvraagDto, BetalingsaanvraagGrondenViewModel>()
			.ForMember(dest => dest.TotaalBedrag, options => options.Ignore());
		CreateMap<GetBetalingsAanvraagByIdentificatieResponse.BetalingsAanvraagLijnDto, BetalingsaanvraagLijnViewModel>()
			.ForMember(dest => dest.Totaal, options => options.Ignore());
		CreateMap<GetBetalingsAanvraagByIdentificatieResponse.StavingsDocumentDto, BetalingsaanvraagDocumentViewModel>();

		CreateMap<GetBetalingsAanvraagByIdentificatieResponse.BetalingsAanvraagDto, BetalingsaanvraagVorderingsstatenViewModel>()
					.ForMember(ba => ba.TotaalBedrag, options => options.Ignore());
		CreateMap<GetBetalingsAanvraagByIdentificatieResponse.BetalingsAanvraagLijnDto, BetalingsaanvraagLijnViewModel>()
					.ForMember(ba => ba.Totaal, options => options.Ignore());
		CreateMap<GetBetalingsAanvraagByIdentificatieResponse.StavingsDocumentDto, BetalingsaanvraagDocumentViewModel>();

		CreateMap<BetalingsaanvraagLijnViewModel, UpdateBetalingsLijnBedragRequest>();	
		
		...
	}
}

2. The fact that the AssertConfigurationIsValid test just isn’t enough to avoid run-time errors.

The first issue can be avoided by putting the container to work.
Let’s just wrap the static automapper stuff into some objects :

public interface IMapper
{
	void Configure();

	//for testing only, curse you C# generics 
	object Map(object target);
}

public interface IMapper<in TFrom, out TTo> : IMapper
{
	TTo Map(TFrom from);
	IEnumerable<TTo> Map(IEnumerable<TFrom> fromList);
}

public class Mapper<TFrom, TTo> : IMapper<TFrom, TTo>
{
	public virtual void Configure()
	{
		AutoMapper.Mapper.CreateMap<TFrom, TTo>();
	}

	public object Map(object @from)
	{
		return Map((TFrom)@from);
	}

	public virtual TTo Map(TFrom @from)
	{
		return AutoMapper.Mapper.Map<TFrom, TTo>(@from);
	}

	public virtual IEnumerable<TTo> Map(IEnumerable<TFrom> fromList)
	{
		return fromList.Select(Map);
	}
}

Create some mappers, f.i. :
public class ProjectDetailMapper : Mapper<Project, ProjectDetailDto> { }

public class GetProjectDetailHandler : IGetProjectDetailHandler
{
	private readonly IGetProjectQuery query;
	private readonly IMapper<Project, ProjectDetailDto> mapper;

	public GetDetailBetalingsAanvraagHandler(
		IGetProjectQuery query,
		IMapper<Project, ProjectDetailDto> mapper)
	{
		this.query = query;
		this.mapper = mapper;
	}

	public ProjectDetailDto Handle(string id)
	{
		return mapper.Map(query.UniqueResult(id));
	}
}

And register them in the container :
public class MyRegistry : Registry
{
	public MyRegistry()
	{
		Scan(cfg =>
		{
			cfg.TheCallingAssembly();
			cfg.WithDefaultConventions();
			cfg.ConnectImplementationsToTypesClosing(typeof(IMapper<,>))
				.OnAddedPluginTypes(ex => ex.Singleton().OnCreation(map => ((IMapper)map).Configure()));
		});
	}
}

Above example assumes you’re using structuremap, but I’ve done the same with both windsor and unity.
Registering the mappers as singletons and calling their Configure method effectively does the same thing as the Boot.Strap() method above.
Except now this bookkeeping code is handled by the container.

The advantage of the method above, I find, is the fact that the mapping can be put right next to the feature, where I feel it belongs.
Mapping is not a cross-cutting concern.

The second issue, however is far more serious.
Look again at the Boot.Strap() example.
If I forget to add a mapping to the initialize method, there is no way I will find out until I actually try to map this in the app. Either through automated acceptance testing or through manual ‘labor’.

So how can we test this better ?

The refactoring described above will help us a lot.

Maintaining the same level :
Using the Boot.Strap() method we can easily test configuration by simple executing the method and then calling : ‘AutoMapper.Mapper.AssertConfigurationIsValid()’.
The same thing can be achieved by retrieving all Mapper derived types, instantiating one of each, call the configure methods and then call AssertConfigurationIsValid, like so :

[Test]
public void ConfigurationIsValid()
{
	var mappers = ScanAssemblyForMappers(); 
	mappers.ForEach(m => m.Configure());
	AutoMapper.Mapper.AssertConfigurationIsValid();
}

Upping the level :
Using the same reflection technique and with the help of quickgenerate we can test that everything we want to map, can actually be mapped.

[Test]
public void CanMap()
{
    var mappers = ScanAssemblyForMappers();
    mappers.ForEach(m => m.Configure());
    mappers.ForEach(m => m.Map(new AutoMapperTestBuilder().One(GetSourceType(m))));
}

The AutoMapperTestBuilder class is derived from quickgenerate’s DomainGenerator and sets up some stuff in the constructor.

public class AutoMapperTestBuilder : DomainGenerator
{
    public AutoMapperTestBuilder()
    {
        With<Mededeling>(
            opt => opt.StartingValue(() =>
                new[]
                {
                    new Mededeling(new StringGenerator(1, 34).GetRandomValue()),
                    new Mededeling(
                        new IntGenerator(100, 999).GetRandomValue(),
                        new IntGenerator(1000, 9999).GetRandomValue(),
                        new IntGenerator(10000, 99999).GetRandomValue())
                }
                .PickOne()));

        OneToOne<Project, Location>((p, g) => p.Location = l);
        ...
    }
}

Now the only that can go wrong is that I declare a dependency on a IMapper and I forget to actually implement this.

Fortunately, in that case, the unit test that verifies the Container configuration fails ;-) .

Posted in C# Musings | Leave a Comment »

Fasterflect

Posted by kilfour on April 13, 2011

Through the ditto project, which I haven’t really tried out in the wild, but I must say, I do like the approach outlined, I came across Fasterflect.

Really nice lib.
It works (i.e. : it has automated tests).
It’s clean.
It’s fast.

Expect some QuickDotNetCheck updates in a month or so.
One of the main reasons that has been holding me back, regarding quickdotnetcheck, is having to write nasty reflection heavy methods.

Fasterflect really makes that kind of stuff a breeze.

And the DeepClone method truly helps out when writing properties involving pre- or postconditions.

Experiments are going on as we speak ;-) .

Posted in C# Musings, Checking Stuff Out | Leave a Comment »

Yet Another NHibernate Query Object Implementation

Posted by kilfour on March 17, 2011

The plumbing :

public interface IProjectionsDefinition { }

public interface IQuery<in TParameter>
{
    TResult UniqueResult<TResult>(TParameter parameter);
    IList<TResult> List<TResult>(TParameter parameter);
}

public abstract class Query<TProjections, TParameter> : IQuery<TParameter> 
    where TProjections : IProjectionsDefinition, new()
{
    private readonly TProjections projectionsDefinition = new TProjections();
    private readonly ISession session;

    protected Query(ISession session)
    {
        this.session = session;
    }

    public TResult UniqueResult<TResult>(TParameter parameter)
    {
        return GetQuery<TResult>(parameter).UniqueResult<TResult>();
    }

    public IList<TResult> List<TResult>(TParameter parameter)
    {
        return GetQuery<TResult>(parameter).List<TResult>();
    }

    protected abstract DetachedCriteria GetCriteria(TParameter parameter);

    private ProjectionList BuildProjectionList<TResult>()
    {
        var projectionList = Projections.ProjectionList();
        foreach (var propertyInfo in typeof(TResult).GetProperties())
        {
            var projectionPropertyInfo = typeof (TProjections).GetProperty(propertyInfo.Name);
            var projection = (IProjection) projectionPropertyInfo.GetValue(projectionsDefinition, null);
            projectionList.Add(projection, propertyInfo.Name);
        }
        return projectionList;
    }

    private ICriteria GetQuery<TResult>(TParameter parameter)
    {
        return
            GetCriteria(parameter)
                .GetExecutableCriteria(session)
                .SetProjection(BuildProjectionList<TResult>())
                .SetResultTransformer(new AliasToBeanResultTransformer(typeof(TResult)));
    }
}

Query example :
public interface ISearchAdresByStraatQuery : IQuery<string> { }

public class SearchAdresByStraatQuery : Query<SearchAdresByStraatQueryProjections, string>, ISearchAdresByStraatQuery
{
    public SearchAdresByStraatQuery(ISession session) 
        : base(session) { }

    protected override DetachedCriteria GetCriteria(string straat)
    {
        return 
            DetachedCriteria.For<Adres>("a")
                .CreateAlias("Straat", "s")
                .CreateAlias("Gemeente", "g")
                .CreateAlias("Postcode", "p")
                .Add(Restrictions.Like("s.Naam", straat));
    }
}

public class SearchAdresByStraatQueryProjections : IProjectionsDefinition
{
    public IProjection Id
    {
        get { return Projections.Cast(NHibernateUtil.String, Projections.Property("a.Id")); }
    }

    public IProjection HuisNummer
    {
        get { return Projections.Property("a.HuisNummer"); }
    }

    public IProjection BusNummer
    {
        get { return Projections.Property("a.BusNummer"); }
    }

    public IProjection Gemeente
    {
        get { return Projections.Property("g.Naam"); }
    }

    public IProjection Postcode
    {
        get { return Projections.Property("p.Waarde"); }
    }

    public IProjection StraatNaam
    {
        get { return Projections.Property("s.Naam"); }
    }

    public IProjection AantalRecords
    {
        get { return Projections.Count("Id"); }
    }
}

Usage :
This :
public class AdresResult
{
    public string Id { get; set; }
    public string Postcode { get; set; }
    public string Gemeente { get; set; }
    public string StraatNaam { get; set; }
    public string HuisNummer { get; set; }
    public string BusNummer { get; set; }
}
...
query.List<AdresResult>("filter");

Results in :
SELECT cast( this_.Id as NVARCHAR(255)) as y0_, this_.BusNummer as y1_, g2_.Naam as y2_, this_.HuisNummer as y3_, p3_.Postcode as y4_, s1_.Naam as y5_ FROM ...

And this :
public class CountDto
{
    public int AantalRecords { get; set; }
}
...
query.UniqueResult<CountDto>("filter");

Results in :
SELECT count(this_.Id) as y0_ FROM ...

Posted in C# Musings, NHibernate | Leave a Comment »

On ConfOrm Flexibility

Posted by kilfour on January 14, 2011

public class MyDomain : IDomainDefinition
{
    private readonly ObjectRelationalMapper orm;
    private readonly Mapper mapper;

    public static MyDomain Create()
    {
        var orm = new ObjectRelationalMapper();
        orm.Patterns.PoidStrategies.Add(new NativePoidPattern());
        orm.Patterns.PoidStrategies.Add(new GuidPoidPattern());
        return
            new MyDomain(orm)
                .DefineTableStrategy()
                .SetExplicitRelations()
                .RegisterPatterns()
                .Customize();
    }

    private ...
}

Posted in C# Musings | Leave a Comment »

On “Encoding monadic computations in C# using iterators”

Posted by kilfour on September 28, 2010

Which is a paper I came across earlier today.

Bit of a long text, but to wet your appetite I’ll highlight a sample.

This :

Console.WriteLine(ReadIntAndMultiplyByTen("5").Apply<int>());

Results in :
Enter a number : Got a valid number !
50

This :
Console.WriteLine(ReadIntAndMultiplyByTen("5s").Apply<int>());

Results in :
Enter a number : none

Let’s look at the ReadIntAndMultiplyByTen method and helpers :
private IEnumerator<IOption> ReadIntAndMultiplyByTen(string s)
{
    var optionStep = ReadInt(s);
    yield return optionStep;
    yield return MultiplyByTen(optionStep);
}

private OptionStep<int> ReadInt(string s)
{
    Console.Write("Enter a number : ");
    return ParseInt(s).AsStep();
}

private OptionResult<int> MultiplyByTen(OptionStep<int> optionStep)
{
    Console.WriteLine("Got a valid number !");
    return OptionResult.Create(optionStep.Value * 10);
}

private Option<int> ParseInt(string s)
{
    int res = 0;
    if (int.TryParse(s, out res))
        return new Some<int>(res);
    return new None<int>();
}

And here’s the interesting bit :
When we pass an invalid int to the ReadInt function the MultiplyByTen function is never evaluated.

Composition
Supposing :

private IEnumerator<IOption> TryCalculate(string s1, string s2) 
{
    var step1 = ReadIntAndMultiplyByTen(s1).Apply<int>().AsStep();
    yield return step1;
    var step2 = ReadIntAndMultiplyByTen(s2).Apply<int>().AsStep();
    yield return step2;
    yield return OptionResult.Create(step1.Value + step2.Value);
}

Then :


Console.WriteLine(TryCalculate("5", "3").Apply<int>());

Enter a number : Got a valid number!
Enter a number : Got a valid number!
80


 Console.WriteLine(TryCalculate("5s", "3").Apply<int>());

Enter a number : none


Console.WriteLine(TryCalculate("5", "3s").Apply<int>());

Enter a number : Got a valid number!
Enter a number : none


Look ma, no null-checks !

Posted in C# Musings, Fun with Continuations | 1 Comment »

On Neurofication

Posted by kilfour on September 24, 2010

A long time ago I was an avid reader of this site.
It’s no longer active, but it still contains a lot of worthwhile articles.

By chance, I came across NeuronDotNet last week and played around a bit.
I wrote a very simple wrapper around it using the Linq Expression techniques and it seems to work quite well.

Suppose this simple class :

public class Story
{
    public virtual int Size { get; set; }
    public virtual TimeSpan ActualTime { get; set; }
    public virtual string CreatedBy { get; set; }
}

For this example I’m going to create the training data myself, but it should ofcourse be real world data.

IEnumerable<Story> stories =
    new GeneratorRepository()
    .With<Story>(
        g => g.For(s => s.CreatedBy, "Me", "Myself", "I")
              .For(s => s.Size, new IntGenerator(1, 10)))
    .With<Story>(s => 
    {
        int ticks = s.Size * 3;
        if (s.CreatedBy == "Me")
            ticks *= 2;
        s.ActualTime = new TimeSpan(ticks); 
        return s; 
    })
    .Randoms<Story>(500);

This gives me 500 random stories where the actual time is three times the size of the story, except if it was created by me. Then the actual time is six times the size of the story.

Here’s the neuro-code :

double normalizer = 100d;
new Neurify<Story>()
    .Input(i => i
        .AddNormalized(s => s.Size, normalizer)
        .AddSymbolic(s => s.CreatedBy, "Me", "Myself", "I"))
    .Output(i => i.AddNormalized(s => s.ActualTime.Ticks, normalizer))
    .Learn(stories, 10000)
    .Solve(story);

It builds the input and output layer, trains the network using the 500 stories from earlier and then attempts to solve a story passed in.

Using this one :

Story story = 
    new Story
    {
        CreatedBy = "I",
        Size = 2
    };

We get something like : 6,31066020786049

Using this one :

Story story = 
    new Story
    {
        CreatedBy = "Me",
        Size = 2
    };

We get something like : 11,1725070796479

Posted in C# Musings | 7 Comments »

On Type Safety : Short

Posted by kilfour on September 23, 2010

Weakly, statically typed languages seem to be a bad idea in the real world.
Stemming from Ansi/C this paradigm has found it’s way into both C# and Java and leads to a lot of unnessary casts, a horrible ‘meta-class’ system and a lot of boiler-plate code.

Weakly dynamically typed languages don’t seem to suffer from this drawback. I can really only talk about SmallTalk in this respect, but it is an absolute joy to program in.
Lately Ruby has attracted a lot of attention and as far as I can see it reuses a lot of good old ST’s constructs (Blocks f.i.).

One thing I don’t agree with, is to say that these kind of languages are the panacea to all developers ails, as strongly statically typed languages do not seem to suffer from aforementioned drawback either.

At the moment there just isn’t any language that fits above description and that has made it into the mainstream.

Posted in C# Musings, Rants | Leave a Comment »

OneReferencePerThreadLifestyleManager

Posted by kilfour on July 2, 2010

Here’s a Castle.Windsor custom lifestyle which might turn out to be quite usefull :

public class Ref
{
    public int RefCount;
    public object Target;
}

public class OneReferencePerThreadLifestyleManager : AbstractLifestyleManager
{
    private readonly Dictionary<long, Ref> references = new Dictionary<long, Ref>();
    private static long Key() { return Thread.CurrentThread.ManagedThreadId; }

    public override object Resolve(CreationContext context)
    {
        if (!references.ContainsKey(Key()))
            references.Add(Key(), new Ref());
        Ref reference = references[Key()];
        if (reference.RefCount == 0)
            reference.Target = base.Resolve(context);
        reference.RefCount++;
        return reference.Target;
    }

    public override bool Release(object instance)
    {
        Ref reference = references[Key()];
        reference.RefCount--;
        if (reference.RefCount == 0)
        {
            reference.Target = null;
            references.Remove(Key());
            return base.Release(instance);
        }
        return false;
    }

    public override void Dispose()
    {
        references.ForEach(kv => Kernel.ReleaseComponent(kv.Value.Target));
    }
}

Or it might turn out to be a much too naive implementation…

I’ll know monday evening ;-)

Posted in C# Musings, Castle, IoC | Leave a Comment »

Read the ‘ken Exception

Posted by kilfour on June 28, 2010

This for me is a basic, _basic_, competence for any developer.
Yet, ‘in the wild’, a lot of developers seem to lack this reflex…

Something goes wrong and they rely on their batman-like deductive powers to resolve the problem.
This usually leads to a number of wild goose chases and a lot of time being lost.
Not to mention the code-bloat that get’s introduced during this ‘optimalization’ and never, ever get’s removed afterwards…

In most cases evaluating the exception message thouroughly points out the issue with impunity and a solution can be devised from that without having to resort to ‘ultra-defensive programmming’.

Posted in C# Musings, Rants | Leave a Comment »

 
Follow

Get every new post delivered to your Inbox.