Failure to pass generic arguments with Castle Windsor

允我心安 提交于 2019-12-20 04:11:37

问题


There seems to be an issue with passing generic arguments when attempting to create a parametrized instance with Castle Windsor

Demo of Failure to Pass Generic Arguments

    private static void Main(string[] args)
    {
        PassGenericParamAtResolutionTime();
        Console.ReadLine();
    }

    private static void PassGenericParamAtResolutionTime()
    {
        Console.WriteLine("Passing generic argument fails");
        var container = new WindsorContainer();
        container.Register(Component.For<ISandCoordinator<Simpleton>>()
                           .ImplementedBy<SandCoordinator<Simpleton>>());
        var runtimeConstructorParam = new GenericManager<Simpleton>(
                                          "This Id Does Not Get Through");
        var runtimeArguments = new Arguments(
                                   new object[] {runtimeConstructorParam});
        var shouldBeParameterizedCoordinator = container
                   .Resolve<ISandCoordinator<Simpleton>>(runtimeArguments);
        Console.WriteLine(shouldBeParameterizedCoordinator.Log);
    }

Console Output

Passing generic argument fails
Birth from parameterless constructor, which should not happen

And if I comment out the parameterless constructor below, I get the following exception:

Castle.MicroKernel.Resolvers.DependencyResolverException was unhandled
Missing dependency.
Component Sand.SandCoordinator`1[[Sand.Simpleton, WindsorSand, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]] has a dependency on Sand.IGenericManager`1[Sand.Simpleton], which could not be resolved.
Make sure the dependency is correctly registered in the container as a service, or provided as inline argument.

Demo Class with Two Constructors

class SandCoordinator<TSimpleton> : ISandCoordinator<TSimpleton>
                                    where TSimpleton : ISimpleton
{
    public SandCoordinator()
    {
        Log = "Birth from parameterless constructor, which should not happen";
    }

    public SandCoordinator(IGenericManager<TSimpleton> manager)
    {
        Log = "Birth from parameterized constructor";
        Log += Environment.NewLine + "Born With Manager: " + manager.Id;
    }        

    public string Log { get; private set; }
}

Solutions / Workarounds?

  • I know that if I create a non-generic type interface ISimpleSandCoordinator : ISandCoordinator<Simpleton> and register the non-generic interface then parametrized resolution works, but I don't want to stop using generic types
  • Should this be filed as a bug in Castle Windsor?

[ Using Castle.Core.dll and Castle.Windsor.dll 3.1.0 (2012-08-05) ]


回答1:


Your SandCoordinator<T> depends on IGenericManager<T>, not GenericManager<T>.

When you're putting a value in Arguments that you want Windsor to use as something else than its concrete type you have to be explicit about it.

new Arguments { { typeof(IGenericManager<Simpleton>), runtimeConstructorParam } };


来源:https://stackoverflow.com/questions/14549577/failure-to-pass-generic-arguments-with-castle-windsor

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!