1
votes

I'm evaluating different IoC containers and did some performance testing. It seems to me that Spring.NET is really bad when it comes to resolving interfaces which are implemented by multiple classes.

E.g. given container of type XmlObjectFactory, I call

foreach (IDummy dummy in container.GetObjectsOfType(interfaceType).Values) {
    dummy.Do();
}

However, it takes 200 times longer than any other IoC frameworks I tried, namely , , , , , and .

Is the performance really that bad, or am I doing it wrong™?

2
There might not be a cache for this scenario, but how often would you do something like this? Having hundreds of definitions would probably cause some head ache but is this a true problem scenario?Marko Lahma
@Thomas: are you posting the results of your testing anywhere? Would be an interesting read.Marijn
@Marijn you can see the code at github.com/thoemmi/di_speed, which I forked from github.com/philipmat/di_speed. Maybe some day I'll blog about my findings ;)Thomas Freudenberg

2 Answers

1
votes

There is the common service locator project, for which the Spring.Net team has provided an implementation. Their implementation of IServiceLocator.GetAllInstances<TService>(); (analogue to the function you're after, IMO) uses:

/// <summary>
/// Resolves service instances by type.
/// </summary>
/// <param name="serviceType">Type of service requested.</param>
/// <returns>
/// Sequence of service instance objects matching the <paramref name="serviceType"/>.
/// </returns>
protected override IEnumerable<object> DoGetAllInstances(Type serviceType)
{
    foreach( object o in _factory.GetObjectsOfType(serviceType).Values)
    {
        yield return o;
    }
}

In this snippet, the GetObjectsOfType(...) is exactly the same interface method as the one you're using; although possibly provided by another concrete implementation than the one you are using.

So from this background and the information you provide I conclude that you are not "doing it wrong", where "it" refers to consuming the GetObjectsOfType(...) method on the spring context you use.

Your presumptions that either you're doing it wrong OR the Spring container performs "really that slow" are not really mutually exclusive IMO. Performance might be impacted by many other things, for instance the exact configuration of your context (e.g. are we dealing with singletons or prototypes, are singletons lazily initialized, ...) and the setup of your benchmark test.

If you still conclude performance can be improved for this scenario, I'm sure the Spring guys would like to hear from you :-).

1
votes

A better option is just to use a simple LINQ query, like this:

var list = appCtx.GetObjectsOfType(typeof(ISomeType)).Values
    .OfType<ISomeType>().ToList();