c# - Castle Windsor: how to pass an argument to the constructor of a 'child' item of the to-be-resolved type -
i'm trying find out best (nicest) way pass argument constructor of child object of auto-resolved parameter.
why? because have program computations against same "production" database (defined in config file, no argument required). needs run work on 'copy' of database. therefore requiring different connection string.
the connection string can supplied on constructor, , not known @ compile time. problem can't (or not know how to) access constructor because buried deep inside generated items.
consider following (simplified) code snippet:
public class example { protected readonly igeneratesomethingfactory factory; public example(igeneratesomethingfactory factory) { factory = factory; } public task dosomething(string connectionstring, string a, string b) { //needs run somehow using supplied connection string ... return task.run(() => factory.createsomething().execute(a, b)); //= task.run(() => new something(new unitofwork(new datacontext(connectionstring))).execute(a, b)); } public task dosomething(string a, string b) { //needs run using default connection string (defined in config) return task.run(() => factory.createsomething().execute(a, b)); } }
the problem lays in first dosomething(...)
function.
note: castle windsor installer looks this:
public class installer : iwindsorinstaller { public void install(iwindsorcontainer container, iconfigurationstore store) { container.addfacility<typedfactoryfacility>(); container.register(component.for<igeneratesomethingfactory>().asfactory()); container.register(classes.fromthisassembly().innamespace("x").withservice.firstinterface()); } }
i'm looking solution that:
- is thread safe
- is easy understand (if not easy think of)
- allows refactoring (so no named arguments "constring" )
- does not require changes other non-relevant code (i.e. setting properties public ... )
- does not call
new
orcontainer.resolve<>()
i have been looking selection handlers, have not found looking for.
ps: i'm using castle windsor 3.3.0
pps: first question, can provide more example code thought should restrict minimum ... let me know if need so.
from example, looks need add parameter typed factory's createsomething
method:
public interface igeneratesomethingfactory { isomething createsomething(string connectionstring); }
then add parameter isomething
implementation:
public class : isomething { public something(string connectionstring) { } }
note how parameter createsomething
, something
's constructor named same. this default behavior parameter matching.
now, pass value along in call dosomething
:
public task dosomething(string connectionstring, string a, string b) { return task.run(() => factory.createsomething(connectionstring).execute(a, b)); }
based on added code, you're trying isn't possible. in nutshell, have resolution hierarchy:
igeneratesomethingfactory.create(string constring)
something.ctor(iunitofwork uow)
unitofwork.ctor(idatacontext context)
datacontext.ctor(string constring)
you're trying pass argument call create
down constructor of datacontext
.
for way enable this, see my answer (to own question). changing default behavior of windsor pass factory creation parameters down objects being resolved instead of first.
first, create class change behavior:
public class defaultdependencyresolverinheritcontext : defaultdependencyresolver { protected override creationcontext rebuildcontextforparameter(creationcontext current, type parametertype) { if (parametertype.containsgenericparameters) { return current; } return new creationcontext(parametertype, current, true); } }
then supply when creating container:
var kernel = new defaultkernel( new defaultdependencyresolverinheritcontext(), new notsupportedproxyfactory()); var container = new windsorcontainer(kernel, new defaultcomponentinstaller());
that's it. when call create
method, constring
parameter passed down objects being registered. obviously can cause problems if have parameters same name! in case, "ambient" parameter (my term) document behavior/parameter name , call day.
i'd love see approach this, save creating factories intermediate types.
Comments
Post a Comment