Resolve named registration dependency in Unity with runtime parameter -
i have following problem. register components , initialize them in unity (example console application):
public class sharepointbootstrapper : unitybootstrapper { ... public object initialize(type type, object parameter) => container.resolve(type, new dependencyoverride<iclientcontext>(container.resolve<iclientcontext>(parameter.tostring())), new dependencyoverride<itenantrepository>(container.resolve<itenantrepository>(parameter.tostring()))); public void registercomponents() { container .registertype<iclientcontext, sharepointonlineclientcontext>(sharepointclientcontext.online.tostring()) .registertype<iclientcontext, sharepointonpremiseclientcontext>(sharepointclientcontext.onpremise.tostring()) .registertype<itenantrepository, documentdbtenantrepository>(sharepointclientcontext.online.tostring()) .registertype<itenantrepository, jsontenantrepository>(sharepointclientcontext.onpremise.tostring()); } } public enum sharepointclientcontext { online, onpremise } class program { static void main(string[] args) { ... bootstrap.registercomponents(); var bla = bootstrap.initialize(typeof(isharepointmanager), sharepointclientcontext.online); } }
so, register components in mvc, wcf, console etc. once registercomponents() , initialize them initialize().
my question is, if want initialize specific named registration @ runtime, e.g. user input, can done otherwise code presented (with injectionfactory or similar)?
this code works fine, i'm not happy implementation. have feeling written in registercomponents() instead of initialize() accepts parameter of type, don't know how it.
or, maybe whole concept wrong? if so, suggest? need resolve named registration parameter known @ runtime, regardless of technology (mvc, wcf, console, ...).
thanks!
instead of doing different registrations, different resolves.
let's need inject iclientcontext
, want different implementations depending on runtime parameter.
i wrote similiar answer here. instead of injecting iclientcontext
, inject iclientcontextfactory
, responsible returning correct iclientcontext
. it's called strategy pattern.
public interface iclientcontextfactory { string context { get; } // add context interface. } public class sharepointonlineclientcontext : iclientcontextfactory { public string context { { return sharepointclientcontext.online.tostring(); } } } // factory resolving iclientcontext. public class clientcontextfactory : iclientcontextfactory { public ienumerable<iclientcontext> _clientcontexts; public factory(iclientcontext[] clientcontexts) { _clientcontexts = clientcontexts; } public iclientcontext getclientcontext(string parameter) { iclientcontext clientcontext = _clientcontexts.firstordefault(x => x.context == parameter); return clientcontext; } }
register them all, did. instead of injecting iclientcontext
inject iclientcontextfactor
.
there solution use func
-factory. @ option 3, in this answer. 1 may argue wrapper service locator-pattern, i'll leave discussion time.
public class clientcontextfactory : iclientcontextfactory { private readonly func<string, iclientcontext> _createfunc; public factory(func<string, iclientcontext> createfunc) { _createfunc = createfunc; } public iclientcontext createclientcontext(string writesto) { return _createfunc(writesto); } }
and use named registrations:
container.registertype<iclientcontext, sharepointonlineclientcontext>(sharepointclientcontext.online.tostring()); container.registertype<iclientcontext, sharepointonpremiseclientcontext>(sharepointclientcontext.onpremise.tostring()); container.registertype<ifactory, factory>( new containercontrolledlifetimemanager(), // or other lifetimemanager. new injectionconstructor( new func<string, iclientcontext>( context => container.resolve<iclientcontext>(context));
usage:
public class myservice { public myservice(iclientcontextfactory clientcontextfactory) { _clientcontextfactory = clientcontextfactory; } public void dostuff(); { var mycontext = sharepointclientcontext.online.tostring(); iclientcontextclientcontext = _clientcontextfactory.createclientcontext(mycontext); } }
Comments
Post a Comment