views:

35

answers:

1

Hi there,

So here's my factory method which takes a parameter...

            container.RegisterInstance<Func<IProductInstance, IQuantityModifier[]>>(
            instance => container.Resolve<IQuantityModifier[]>());

Now one of the items returned by the array takes the IProductInsance parameter in its constructor. I can't figure out how to get Unity to pass the parameter in or, if I make the constructor argument a property instead, how to get Unity to set the property. No amount of dependency overrides, injection parameters etc. seem to do anything.

Of course both of these situations would be easy if I was resolving a single instance but with an array Unity doesn't seem to fully process each item.

Any ideas? What I've ended up doing is stuff like this...

            container.RegisterInstance<Func<IProductInstance, IQuantityModifier[]>>(
            instance =>
                {
                    var items = container.Resolve<IQuantityModifier[]>();

                    QuantityModifier item = items.OfType<QuantityModifier>().SingleOrDefault();

                    if (item != null)
                    {
                        item.ProductInstance = instance;
                    }

                    return items;
                };

I suppose ideally the item that requires the parameter would be created by a factory but then Unity would have to pass the correct value into the factory and execute it.

Cheers, Ian.

+1  A: 

Sadly, you've hit a bug in the container. A resolve override should do the right thing here. I suspect it's the same underlying cause as this bug: http://unity.codeplex.com/workitem/8777

I'm looking in the source code for the container, the problem is in this method in ArrayResolutionStrategy:

    private static object ResolveArray<T>(IBuilderContext context)
    {
        IUnityContainer container = context.NewBuildUp<IUnityContainer>();
        List<T> results = new List<T>(container.ResolveAll<T>());
        return results.ToArray();
    }

The current set of overrides is part of the current build context, not the container itself, so when it grabs the container and reresolves that context is lost.

Darn, I'll have to figure out how to fix this one.

Chris Tavares
Thanks for your reply. I thought it was a bug. ;) What do you think about the idea I mentioned of having ResoleAll execute any factories which return an item of the type being resolved?
Ian Warburton
If you used the InjectionFactory syntax to register the item in question, Unity will execute it as part of a ResolveAll now. The trick is getting that override thing in there.
Chris Tavares