c# - Register generic factory -


i have icommand , icommandhandler<tcommand> interfaces , need inject factory:

public class commandprocessor {     private readonly func<type, icommandhandler<icommand>> _handler;      public commandprocessor(func<type, icommandhandler<icommand>> handler)     {         _handler = handler;     } } 

to have ability following:

public void process(icommand command) {     var handler = _handler(command.gettype());      if (handler != null)     {         handler.handle(command);     }      throw ... } 

i tried register factory:

    builder.register<func<type, icommandhandler<icommand>>>(context => type =>         {             var handlertype = context.resolve(type);             return (icommandhandler<icommand>) handlertype;         }); 

but got following exception:

the requested service 'qvocado.commands.information.postproblemcommentcommand' has not been registered. avoid exception, either register component provide service, check service registration using isregistered(), or use resolveoptional() method resolve optional dependency.

seems me commandprocessor useless abstraction in system. instead of letting consumer depend on commandprocessor, let them depend directly on 1 or multiple closed versions of icommandhandler<tcommand> interface. solves problem elegantly, because autofac can resolve dependencies you. besides, prevents breaking object/dependency graph sub graphs (which happens when use factory) , makes easier verify di configuration.

perhaps reason introduced commandprocessor abstraction because otherwise have inject many icommandhandler<tcommand> dependencies consumers. in case violating single responsibility principle , leads classes hard maintain , hard test.

removing commandprocessor removes need implement icommand on each command message.

note delegate registered not resolves command handler, command. have create closed generic version of icommandhandler<tcommand> interface using makegenerictype this. here proper implementation:

builder.register<func<type, icommandhandler<icommand>>>(     context => commandtype =>     {         var handlertype = typeof(icommandhandler<>)             .makegenerictype(commandtype);         var handler = context.resolve(handlertype);         return (icommandhandler<icommand>)handler;     }); 

Comments

Popular posts from this blog

Why does Ruby on Rails generate add a blank line to the end of a file? -

keyboard - Smiles and long press feature in Android -

node.js - Bad Request - node js ajax post -