Showing posts with label IEnumerable. Show all posts
Showing posts with label IEnumerable. Show all posts

Thursday, August 27, 2015

IEnumerable Unity Injection

A few years ago I blogged about how to add Lazy Unity Injection, and then a year after that Unity 3 added that feature. Recently I had to dust off this old code to do something similar...

I wanted to use Unity to inject a collection of registered types into one of my services. To do this directly from the container you would use named registrations and ResolveAll. However if you just try to resolve an IEnumerable of a type in a constructor, then Unity will just try to use Resolve and thus throw an InvalidOperationException.

We can easily "fix" this by registering an extension with our container.

Extension

public class EnumerableContainerExtension : UnityContainerExtension
{
    protected override void Initialize()
    {
        Context.Policies.Set<IBuildPlanPolicy>(
            new EnumerableBuildPlanPolicy(),
            typeof(IEnumerable<>));
    }
 
    private class EnumerableBuildPlanPolicy : IBuildPlanPolicy
    {
        public void BuildUp(IBuilderContext context)
        {
            if (context.Existing != null)
                return;
 
            var container = context.NewBuildUp<IUnityContainer>();
            var typeToBuild = context.BuildKey.Type.GetGenericArguments()[0];
 
            context.Existing = container.ResolveAll(typeToBuild);
 
            DynamicMethodConstructorStrategy.SetPerBuildSingleton(context);
        }
    }
}

Monday, September 15, 2014

Possible Multiple Enumeration Warning

Someone recently asked me what the "Possible Multiple Enumeration" warning means. The IEnumerable interface only exposes a single method, GetEnumerator. This means that every and every time we want to traverse the enumerable we have to start at the beginning and iterate the entire enumeration again.

public interface IEnumerable<out T> : IEnumerable
{
    IEnumerator<T> GetEnumerator();
}
 
public interface IEnumerable
{
    IEnumerator GetEnumerator();
}

Whenever you see the Possible Multiple Enumeration warning the compiler is trying to tell you that your code my be sub-optimal at run time because it will have to completely traverse the enumerable multiple times.

More importantly, the compiler can not be sure what that enumeration will entail!

Why could that be bad?

With a collection we know what the contents and implementation of the enumerable are, and we are able to know the run time implications of iteration over that collection. However an IEnumerable is an abstraction and not a guaranteed implementation, meaning that it may represent a very inefficient enumeration.

For example, an object relational mapping (ORM) framework may expose an IEnumerable that loads it's items from a database on each iteration. Other IEnumerables may be computing complex and CPU intensive operations during iteration. The simple fact is that when your code is iterating over an IEnumerable you just can not be sure what is actually happening behind the interface.

This is not necessarily a bad thing, but that uncertainty does merit a warning.

Real Time Web Analytics