Register in Windsor an open generic type component

2019-07-23 19:27发布

I hope the title makes at least some sense.

I have the situation as in the code below. The test passes, but I would like to register

GenericCommandHandler<> 

as open generic type as implementation for

IHandler<GenericCommand<>>

I can live with the thing below, because the number of types given to GenericCommandHandler is limited and I can register them all individually, but would like something more "automated".

using Castle.MicroKernel.Registration;
using Castle.Windsor;
using NUnit.Framework;

[TestFixture]
public class Class1
{
   [Test]
   public void t()
   {
      using( var container = new WindsorContainer() )
      {
         // HOW TO REGISTER IT AS OPEN GENERIC TYPE?
         container.Register(
            Component.For<IHandler<GenericCommand<object>>>()
               .ImplementedBy<GenericCommandHandler<object>>() );

         var handler = container.Resolve<IHandler<GenericCommand<object>>>( );
      }
   }
}

public interface IHandler<TCommand>
{
   void Handle(TCommand o);
}

public class GenericCommand<T>
{
}

public class GenericCommandHandler<T> : IHandler<GenericCommand<T>>
{
   public void Handle( GenericCommand<T> o )
   {
   }
}

2条回答
贪生不怕死
2楼-- · 2019-07-23 20:09

IIRC Windsor requires generic type definitions (i.e. types you can call MakeGenericType() on).

IHandler<GenericCommand<>> (pseudo code, doesn't even compile) is not a generic type definition, you can't call MakeGenericType() on it because the free type parameter is nested.

See http://www.ideone.com/0WsMZ for a little test that should clarify this. See also the MSDN page about Type.IsGenericType, which defines "generic type definition", "open generic types", etc.

查看更多
倾城 Initia
3楼-- · 2019-07-23 20:14

Artur,

What you're asking for is support for semi-closed generics and as Mauricio mentioned there's no API in .NET framework to support these. You kind of could hack this in, so that it works in most of the cases (there's a ticket open in Windsor's issue tracker to support this) but lack of descent built in API would mean that making it work would be a significant effort.

You can have a look at this blogpost of mine, which tackles the issue for specific component. Perhaps that would be enough for your needs.

查看更多
登录 后发表回答