Skip to content

Wrong c'tor get's choosed #136

@stffabi

Description

@stffabi

Accordingly to https://github.com/castleproject/Windsor/blob/master/docs/how-constructor-is-selected.md the constructor with the most satisfiable parameters gets picked.

In the following example, Windsor chooses the parameterless c'tor on MyControl although the c'tor with the parameter of type IMyUtils<ArrayList> can be resolved as proofed by lResolvedFixedHelper

Registering a generic type-unbound implementation for IMyHelper<> seems to fix the problem and the expected c'tor is called on MyControl.

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Castle.MicroKernel.Registration;
using Castle.Windsor;

namespace ConsoleApplication15
{
    class Program
    {
        static void Main(string[] args)
        {
            var lContainer =  new WindsorContainer();
            var lGenericUtilsReg =
                Component.For(typeof(IMyUtils<>)).
                ImplementedBy(typeof(MyGenericUtilsImpl<>));

            lContainer.Register(lGenericUtilsReg);

            var lFixedHelperReg =
               Component.For(typeof(IMyHelper<ArrayList>)).
               ImplementedBy(typeof(MyArrayListFixedHelperImpl));

            lContainer.Register(lFixedHelperReg);

            var lControlReg =
               Component.For(typeof(MyControl)).
               ImplementedBy(typeof(MyControl));

            lContainer.Register(lControlReg);

            // Commenting the following code in, let's the example run as expected.
            //var lGenericHelperReg =
            //   Component.For(typeof(IMyHelper<>)).
            //   ImplementedBy(typeof(MyGenericHelperImpl<>));

            //lContainer.Register(lGenericHelperReg);

            var lResolvedFixedHelper = lContainer.Resolve<IMyHelper<ArrayList>>();
            if (lResolvedFixedHelper == null)
            {
                throw new ApplicationException("Should not happen.");
            }

            var lResolvedControl = lContainer.Resolve<MyControl>();
            if (lResolvedControl == null)
            {
                throw new ApplicationException("Should not happen.");
            }
        }
    }

    public class MyControl
    {
        public MyControl()
        {
            throw new ApplicationException("Should not be used.");
        }

        public MyControl(IMyUtils<ArrayList> aUtils)
        {
            Console.WriteLine("MyControl: ctor " + aUtils.GetType().Name);
        }
    }

    public class MyGenericUtilsImpl<T> : IMyUtils<T>
    {
        public MyGenericUtilsImpl(IMyHelper<T> aUtils)
        {
            Console.WriteLine("MyGenericUtilsImpl: ctor " + aUtils.GetType().Name);
        }
    }

    public class MyGenericHelperImpl<T> : IMyHelper<T>
    {
        public MyGenericHelperImpl()
        {
            Console.WriteLine("MyGenericHelperImpl: ctor");
        }
    }

    public class MyArrayListFixedHelperImpl : IMyHelper<ArrayList>
    {
        public MyArrayListFixedHelperImpl()
        {
            Console.WriteLine("MyArrayListFixedHelperImpl: ctor");
        }
    }

    public interface IMyUtils<T> { }

    public interface IMyHelper<T> { }
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions