I have a class which takes an IEnumerable
constructor parameter which I want to resolve with Unity and inject an array of objects. These simple classes illustrate the problem.
public interface IThing
{
int Value { get; }
}
public class SimpleThing : IThing
{
public SimpleThing()
{
this.Value = 1;
}
public int Value { get; private set; }
}
public class CompositeThing : IThing
{
public CompositeThing(IEnumerable<IThing> otherThings)
{
this.Value = otherThings.Count();
}
public int Value { get; private set; }
}
Say I want to inject four SimpleThing
in to CompositeThing
. I've tried several variations on the following Unity configuration.
<alias alias="IThing" type="TestConsoleApplication.IThing, TestConsoleApplication" />
<alias alias="SimpleThing" type="TestConsoleApplication.SimpleThing, TestConsoleApplication" />
<alias alias="CompositeThing" type="TestConsoleApplication.CompositeThing, TestConsoleApplication" />
<container>
<register type="IThing" mapTo="SimpleThing" name="SimpleThing" />
<register type="IThing" mapTo="CompositeThing" name="CompositeThing">
<constructor>
<param name="otherThings">
<array>
<dependency type="SimpleThing"/>
<dependency type="SimpleThing"/>
<dependency type="SimpleThing"/>
<dependency type="SimpleThing"/>
</array>
</param>
</constructor>
</register>
</container>
However I get the error message The configuration is set to inject an array, but the type IEnumerable`1 is not an array type. If I change the constructor parameter to be IThing[]
it works, but I don't want to do that. What do I need to do to my Unity configuration to get this to work?
Here's one solution that I've found, but it's a bit naff. You need a wrapper class to help Unity recognise that an array is IEnumerable
.
public class ArrayWrapper<T> : IEnumerable<T>
{
public ArrayWrapper(T[] things)
{
this.things = things;
}
private IEnumerable<T> things;
IEnumerator<T> IEnumerable<T>.GetEnumerator()
{
return this.things.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return this.things.GetEnumerator();
}
}
You can then configure Unity to inject one of these, using Ethan's EnumberableThing
idea.
<alias alias="IThing" type="TestConsoleApplication.IThing, TestConsoleApplication" />
<alias alias="SimpleThing" type="TestConsoleApplication.SimpleThing, TestConsoleApplication" />
<alias alias="CompositeThing" type="TestConsoleApplication.CompositeThing, TestConsoleApplication" />
<alias alias="EnumerableThing" type="System.Collections.Generic.IEnumerable`1[[TestConsoleApplication.IThing, TestConsoleApplication]], mscorlib"/>
<alias alias="ThingArrayWrapper" type="TestConsoleApplication.ArrayWrapper`1[[TestConsoleApplication.IThing, TestConsoleApplication]], TestConsoleApplication"/>
<container>
<register type="EnumerableThing" mapTo="ThingArrayWrapper">
<constructor>
<param name="things">
<array>
<dependency type="SimpleThing"/>
<dependency type="SimpleThing"/>
<dependency type="SimpleThing"/>
<dependency type="SimpleThing"/>
</array>
</param>
</constructor>
</register>
<register type="IThing" mapTo="SimpleThing" name="SimpleThing" />
<register type="IThing" mapTo="CompositeThing" name="CompositeThing">
<constructor>
<param name="otherThings" dependencyType="EnumerableThing" />
</constructor>
</register>
</container>
Like I say though, a bit naff and awkward when you want another CompositeThing
with three, five, six things etc.
Surely Unity should be able to recognise that an array is IEnumberable
and inject it?