c# - Properly using parameterized Factory.Create() method using DI -
my factory using method injection because thought best way make far. besides, doubt thing after having call on create
method within dependent object.
the way might think of whilst continuing use parameterized factory create
method, inject dependencies directly in mainpresenter
may provide dependencies method, , dislike it. dislike because not mainpresenter
depends on icustomermanagementview
, icustomerdetailpresenterfactory
, it's dependency. feel i'm sabotaging own code doing so.
mainpresenter
public class mainpresenter : presenter<imainview>, imainviewuihandler { public mainpresenter(imainview view , icustomermanagementpresenterfactory customermanagementfactory) : base(view) { this.customermanagementpresenterfactory = customermanagementpresenterfactory; } public void managecustomers() { // following line causing trouble. // can see per icustomermanagementpresenterfactory code sample, // create() method takes 2 parameters: // 1. icustomermanagementview, , // 2. icustomerdetailpresenterfactory // hence have provide dependencies manually, guess. // avoid @ cost. var customermanagementpresenter = customermanagementpresenterfactory.create(); customermanagementpresenter.showview(); } }
icustomermanagementpresenterfactory
public interface icustomermanagementpresenterfactory { // here. though ask ninject inject dependencies, need // provide values parameters when calling method within // mainpresenter class. compiler won't let me otherwise! , // makes sense!... [inject] customermanagementpresenter create(icustomermanagementview view , icustomerdetailpresenterfactory factory); }
imainview
public interface imainview : iview, ihasuihandler<imainviewuihandler> { }
imainviewuihandler
public interface imainviewuihandler : iuihandler { void managecustomers(); }
iuihandler
public interface iuihandler { }
ihasuihandler
public interface ihasuihandler<h> h : iuihandler { h handler { set; } }
mainform
public partial class mainform : form, imainview { public mainform() { initializecomponent(); } public imainviewuihandler handler { private { return handler; } set { sethandler(value); } } }
compositionroot
public class compositionroot { private compositionroot() { } public static ikernel buildobjectgraph() { ikernel kernel = new standardkernel(); bindfactories(kernel); bindviews(kernel); } private static void bindfactories(ikernel kernel) { kernel.bind(services => services .from(appdomain.currentdomain .getassemblies() .where(a => !a.fullname.contains("tests"))) .selectallinterfaces() .endingwith("factory") .bindtofactory() ); } private static void bindviews(ikernel kernel) { kernel.bind(services => services .from(appdomain.currentdomain .getassemblies() .where(a => a.fullname.contains("windows") && !a.fullname.contains("tests")) .selectallclasses() .endingwith("form") .bindselection((type, basetype) => type .getinterfaces() .where(iface => iface.name.endswith("view")) ) ); } }
so wonder, best implement icustomermanagementpresenterfactory
, bind implementer within compositionroot
, provide dependencies through constructor injection create
method shall no longer take arguments, or shall make otherwise?
what of writing simple interface ninject me factory, , no code necessary build instance of desired type. besides, when constructor of class created uses constructor injection, seems impossible have simple factory interface bound factory, , 1 need implement factory interface hand.
what did right/wrong?
as matter of fact don't need pass parameters factory create
method @ - except in case parameters need passed "down" because cannot bound in composition root (for example input value). however, passing such parameters constructors code smell. mostly, it's better idea pass these parameters methods instead of constructors (for example: adder.add(5,3);
, not new adder(5, 3).computeresult();
.
now consider following example, works fine:
public class dependency1 { } public interface idependency2 { } public class dependency2 : idependency2 { } public interface ibar { } public class bar : ibar { public bar(dependency1 d1, idependency2 d2) { } } public interface ibarfactory { ibar create(); } var kernel = new standardkernel(); kernel.bind<ibarfactory>().tofactory(); kernel.bind<ibar>().to<bar>(); kernel.bind<dependency1>().toself(); kernel.bind<idependency2>().to<dependency2>(); var factory = kernel.get<ibarfactory>(); var bar = factory.create(); bar.should().beoftype<bar>();
even though bar
takes 2 constructor arguments, generated ibarfactory
's create()
method not specify so. no problem, ninject resolve automatically.
now let me give example .tofactory()
results in. consider factory:
public interface isomefactory { isomething create(string parameter1); }
will result in (remark: it's realised interceptors , not weaving it, example simplificiation):
public class somefactory : isomefactory { private readonly iresolutionroot resolutionroot; public somefactory(iresolutionroot resolutionroot) { this.resolutionroot = resolutionroot; } public isomething create(string parameter1) { this.resolutionroot.get<isomething>(new constructorargument("parameter1", parameter1); } }
the constructorargument
tells ninject pass value of parameter1
ctor-parameter named "parameter".
all other parameters resolved "as usual". if constructor parameter cannot resolved (neither passed parameter nor bound) ninject throw exception stating parameter cannot resolved.
Comments
Post a Comment