dependency injection - Castle Windsor Typed Factory Facility with generics -


i'm trying register factory resolve array of event handlers defined follow:

    public interface ievent { }      public class eventa : ievent { }     public class eventb : ievent { }     public class eventc : ievent { }       public interface ihandler<tevent> tevent : ievent     {         void handle(tevent ev);     }       public class handlerx : ihandler<eventa>, ihandler<eventb>     {         public void handle(eventa ev)         {             throw new notimplementedexception("handle eventa");         }          public void handle(eventb ev)         {             throw new notimplementedexception("handle eventb");         }     }      public class handlery : ihandler<eventb>, ihandler<eventc>     {         public void handle(eventb ev)         {             throw new notimplementedexception("handle eventb");         }          public void handle(eventc ev)         {             throw new notimplementedexception("handle eventc");         }     }      public interface handlerfactory     {         object[] gethandlersforevent(ievent ev);     } 

basically each event can have more handlers , each handler can handle multiple events. want factory return object[] because @ runtime don't know closed generic types returned.

i tried approach descirbed krzysztof koźmic http://kozmic.pl/2010/03/11/advanced-castle-windsor-ndash-generic-typed-factories-auto-release-and-more/ still have problems. question boils down types return custom type deriving defaulttypedfactorycomponentselector.

i tried many variations of following:

public class handlerselector : defaulttypedfactorycomponentselector     {         protected override typedfactorycomponent buildfactorycomponent(methodinfo method, string componentname, type componenttype, system.collections.idictionary additionalarguments)         {             type eventtype = null;             foreach (var k in additionalarguments.values)             {                 eventtype = k.gettype();             }              var handlertype = typeof(ihandler<>).makegenerictype(eventtype);             var handlerarraytype = handlertype.makearraytype();             //return handlerarraytype;             return new typedfactorycomponentcollection(handlertype, additionalarguments);         }          protected override type getcomponenttype(methodinfo method, object[] arguments)         {             return typeof (object);             /*             var message = arguments[0];             var handlertype = typeof(ihandler<>).makegenerictype(message.gettype());             var handlerarraytype = handlertype.makearraytype();             return handlerarraytype;              */         }          /*         public typedfactorycomponent selectcomponent(methodinfo method, type type, object[] arguments)         {             var message = arguments[0];             var handlertype = typeof(ihandler<>).makegenerictype(message.gettype());             var result = new typedfactorycomponentcollection(handlertype.makearraytype(), new arguments(arguments));             return result;         }*/     } 

with windsor installer defined as:

public class installer : iwindsorinstaller     {         public void install(iwindsorcontainer container, iconfigurationstore store)         {             container.addfacility<typedfactoryfacility>()                 .register(                     component.for<handlerselector>().implementedby<handlerselector>(),                     component.for<autoreleasehandlerinterceptor>(),                     alltypes.fromassemblycontaining<program>()                         .basedon(typeof(ihandler<>))                         .withservice.base()                         .configure(c => c.lifestyle.is(lifestyletype.transient)                                             .interceptors<autoreleasehandlerinterceptor>()),                     component.for<handlerfactory>().asfactory(c => c.selectedwith<handlerselector>()));         }     } 

when calling factory.gethandlersforevent(ev); exception complaining array type mismatch: "attempted access element type incompatible array."

stack trace:

at system.collections.generic.dictionary2.valuecollection.copyto(tvalue[] array, int32 index)
@ system.collections.generic.dictionary
2.valuecollection.system.collections.icollection.copyto(array array, int32 index)
@ castle.microkernel.defaultkernel.resolveall(type service, idictionary arguments) in e:\oss.code\castle.windsor\src\castle.windsor\microkernel\defaultkernel_resolve.cs:line 285
@ castle.facilities.typedfactory.typedfactorycomponentcollection.resolve(ikernel kernel) in e:\oss.code\castle.windsor\src\castle.windsor\facilities\typedfactory\typedfactorycomponentcollection.cs:line 39
@ castle.facilities.typedfactory.internal.typedfactoryinterceptor.resolve(iinvocation invocation) in e:\oss.code\castle.windsor\src\castle.windsor\facilities\typedfactory\internal\typedfactoryinterceptor.cs:line 173
@ castle.facilities.typedfactory.internal.typedfactoryinterceptor.intercept(iinvocation invocation) in e:\oss.code\castle.windsor\src\castle.windsor\facilities\typedfactory\internal\typedfactoryinterceptor.cs:line 83
@ castle.dynamicproxy.abstractinvocation.proceed()
@ castle.proxies.handlerfactoryproxy.gethandlersforevent(ievent ev)
@ castlewindsortests.program.tryit(handlerfactory factory) in c:\users\user\documents\visual studio 2010\projects

how implement handlerselector works factory defined returning object[] whereas real objects @ runtime closed generic types? i'll happy pointed existing documentation guidelines implementors of itypedfactorycomponentselector / defaulttypedfactorycomponentselector. yes, tried http://docs.castleproject.org/(s(kwaa14uzdj55gv55dzgf0vui))/windsor.typed-factory-facility-interface-based-factories.ashx here's not above types.

i don't want introduce service locator (instead of factory) ;).

to answer own question:

i must've been blind. after reading more closely xmldoc of methods override, changing handlerselector following solved problem:

public class handlerselector : defaulttypedfactorycomponentselector {     protected override typedfactorycomponent buildfactorycomponent(methodinfo method, string componentname, type componenttype, system.collections.idictionary additionalarguments)     {                         return new typedfactorycomponentcollection(componenttype, additionalarguments);     }      protected override type getcomponenttype(methodinfo method, object[] arguments)     {         var message = arguments[0];         var handlertype = typeof(ihandler<>).makegenerictype(message.gettype());         return handlertype;     } } 

Comments

Popular posts from this blog

c# - how to write client side events functions for the combobox items -

exception - Python, pyPdf OCR error: pyPdf.utils.PdfReadError: EOF marker not found -