0

J'ai un WindsorContainer avec un IModelInterceptorsSelector. Cela fonctionne bien sauf pour les composants qui n'ont pas d'implémentation (par exemple, tous les comportements sont gérés dynamiquement par un IInterceptor).Castle Windsor Proxy pour l'interface sans cible

Si je tente de résoudre un composant avec une seule interface, je reçois:

Castle.MicroKernel.ComponentActivator.ComponentActivatorException occurred 
    Message=Could not find a public constructor for type ConsoleApplication1.IInterfaceOnlyService. Windsor can not instantiate types that don't expose public constructors. To expose the type as a service add public constructor, or use custom component activator. 
    Source=Castle.Windsor 
    StackTrace: 
     at Castle.MicroKernel.ComponentActivator.DefaultComponentActivator.FastCreateInstance(Type implType, Object[] arguments, Type[] signature) 

Mais si je spécifier manuellement l'intercepteur au moment de l'enregistrement, il fonctionne très bien. Est-ce un bug à Windsor ou est-ce que je fais quelque chose de mal?

Le code de reproduire est assez simple:

 var container = new WindsorContainer(); 
     container.Kernel.ProxyFactory.AddInterceptorSelector(new Selector()); 
     container.Register(Component.For<TestInterceptor>()); 
     container.Register(Component.For<IInterfaceOnlyService>()); // this doesn't work 
     // container.Register(Component.For<IInterfaceOnlyService>().Interceptors<TestInterceptor>()); // this works 
     var i = container.Resolve<IInterfaceOnlyService>(); 


    public class Selector : IModelInterceptorsSelector 
    { 
     public bool HasInterceptors(ComponentModel model) 
     { 
      return model.Service != typeof (TestInterceptor); 
     } 

     public InterceptorReference[] SelectInterceptors(ComponentModel model, InterceptorReference[] interceptors) 
     {     
      return new[] { InterceptorReference.ForType<TestInterceptor>() }; 
     } 
    } 

Merci.

+0

Je ne savais pas que vous pourriez le faire avec Windsor et mal lu la question à cause de cela. Suppression de la réponse –

Répondre

0

Cela semble définitivement être un bug à Windsor. Il semble que cela ait à voir avec l'acceptation d'un InterceptorGroup pour les composants sans cible. C'est-à-dire:

fonctionne.

container.Register(Component.For<IInterfaceOnlyService> 
().Interceptors(InterceptorReference.ForType(typeof(TestInterceptor)))); 

En regardant la source Castle, la différence est que le premier ajoute adescriptor directement:

return this.AddDescriptor(new InterceptorDescriptor<TService>(new 
InterceptorReference[] { new InterceptorReference(typeof(TInterceptor)) })); 

Mais le second utilise un groupe intercepteur interne:

return new InterceptorGroup<TService>((ComponentRegistration<TService>) this, 
interceptors); 

En conséquence, cette semble être un bug dans InterceptorGroups.

Ma solution de contournement (bien que hacky) consiste à utiliser mon LazyComponentLoader pour appeler directement AddDescriptor.