dependency injection - What are the best practicies concerning bootstraping and ioc container? -
dependency injection - What are the best practicies concerning bootstraping and ioc container? -
here story :
i'm working on not big wpf / c# application implementing (for first time) inversion of command help of unity framework. finished. problem come "bootstrapper" class, in wich register types in unity container. of import number of classes involved, bootstrapper turned much more longer i'd , despite comments/regions, maintain pain else me. wondering if there improve way handle registeration. thinking, maybe :
1. "what complaining of ? every 1 way" mmmh, uncertainty it
2. have misunderstood involvement of ioc , much of classes need registeration. well, involvement of ioc ?
3. created ravioli app much different classes, should merge some think did best find balance
4.i should not have 1 macro bootstrapper, main 1 should phone call specialized ones, 1 librairy example okay, begins sound good. after all, librairies should know improve others contain. absolutely don't know how handle without having container tramping in every libraries, these having dependency on unity...
so, 1 of points good, or did miss post nice way handle registeration, comfort of maintainability, utilize ?
ps : did not mentioned technos in tags, because question seemed pretty mutual every app working ioc container
edit : code added bootstrepper (misnamed bootloader)it's old version, has grow longer now, +15-20%
class="lang-cs prettyprint-override">class bootloader { public void run() { #region splash screen sequenceur.ihm.views.splashscreen screen = new sequenceur.ihm.views.splashscreen(); splashscreenviewmodel screenvm = new splashscreenviewmodel(); screen.show(); #endregion #region container initialization unitycontainer container = new unitycontainer(); container.registertype<imainworker, overseer>(); #endregion #region dal registeration container.registertype<imanagedata<product>, lazyproductfilesmanager>(); container.registertype<imanagedata<program>, lazyprogramfilesmanager>(); container.registertype<imanagedata<sequenceresult>, lazyresultfilesmanager>(); #endregion #region bol registeration //sequence preparation container.registertype<iprovideproducts, eagercancellableproductprovider>(); container.registertype<iprovideprograms, eagercancellableprogramprovider>(); container.registertype<ipreparesequence, sequenceinitializer>(); //sequence processing container.registertype<imanageplugins, mefpluginmanager>(new containercontrolledlifetimemanager()); //result persistence container.registertype<ipersistsequenceresult, sequenceresultpersister>(); container.registertype<imanagereport, reporter>(new containercontrolledlifetimemanager()); #endregion #region update registeration container.registertype<imanageconnection, sqlconnectionmanager>(); container.registertype<iupdateproducts, productsupdater>(); container.registertype<iupdateprograms, programsupdater>(); container.registertype<iuploadresults, resultsuploader>(); container.registertype<iupdate, developmentupdater>(new containercontrolledlifetimemanager()); #endregion #region helpers registeration //hashing container.registertype<ihashstring, sha256stringhasher>(); //configuration container.registertype<ipersistconfiguration, configurationpropertiespersister>(); container.registertype<iconfiguration, editableconfiguration>(); //logging container.registertype<imanageloggers, nloggermanager>(); //messengers container.registertype<imessagepublisher<exception>, simplemessenger<exception>>(new containercontrolledlifetimemanager()); container.registertype<imessagepublisher<abortrequest>, simplemessenger<abortrequest>>(new containercontrolledlifetimemanager()); container.registertype<imessagepublisher<configdata>, simplemessenger<configdata>>(new containercontrolledlifetimemanager()); container.registertype<imessagepublisher<sequenceaction>, simplemessenger<sequenceaction>>(new containercontrolledlifetimemanager()); container.registertype<imessagepublisher<updaterstatus>, simplemessenger<updaterstatus>>(new containercontrolledlifetimemanager()); container.registertype<imessagelistener<abortrequest>>(); #endregion #region ihm registeration container.registertype<iloadmenuviews, simplemenuviewloader>(); container.registertype<imanagescene, scenemanager>(); container.registertype<iprovideod, winformofdialog>(); #endregion #region converters registeration container.registertype<iconvertmodels<parameter, dbparameterresult>, parametermodelsconverter>(); container.registertype<iconvertmodels<sequenceactionresult, dbactionresult>, actionmodelsconverter>(); container.registertype<iconvertmodels<tag, dbtag>, tagmodelsconverter>(); container.registertype<iconvertmodels<country, dbcountry>, countrymodelsconverter>(); container.registertype<iconvertmodels<segment, dbsegment>, segmentmodelsconverter>(); container.registertype<iconvertmodels<caracteristic, dbcaracteristic>, caracteristicmodelsconverter>(); container.registertype<iconvertmodels<value, dbvalue>, valuemodelsconverter>(); container.registertype<iconvertmodels<range, dbrange>, rangemodelsconverter>(); container.registertype<iconvertmodels<subrange, dbsubrange>, subrangemodelsconverter>(); container.registertype<iconvertmodels<product, dbproduct>, productmodelsconverter>(); container.registertype<iconvertmodels<program, dbprogram>, programmodelsconverter>(); container.registertype<iconvertmodels<tag, dbtag>, tagmodelsconverter>(); #endregion #region start shellview mainview = new shellview(); mainview.datacontext = container.resolve<shellviewmodel>(); screen.close(); mainview.show(); #endregion } }
the famous mark seemann has written blog post explaining when utilize di container. says usefulness of di container limited when utilize 'explicit register', having line of code per registered type in container (which doing). real benefit starts when utilize convention on configuration. convention on configuration able register big amount of types in single line of code, , prevent composition root becoming maintenance nightmare.
although i'm not on same page , see utilize 'explicit register' model, right gain benefit using convention on configuration. in application there few clear spots benefit convention on configuration , that's when registering generic abstractions such imanagedata<t>
, iconvertmodels , imessagepublisher<tmessage>
.
so can create next convenient extension method:
class="lang-cs prettyprint-override">public static void registermanyforopengeneric(this unitycontainer container, type opengenericservicetype, params assembly[] assemblies) { container.registertypes( type in allclasses.fromassemblies(assemblies) type.getinterfaces().any(i => i.isgenerictype && i.getgenerictypedefinition() == opengenericservicetype) select type, withmappings.frommatchinginterface, withname.default); }
with extension method can cut down registrations of generic abstractions following:
class="lang-cs prettyprint-override">var assemblies = appdomain.currentdomain.getassemblies(); container.registermanyforopengeneric(typeof(imanagedata<>), assemblies); container.registermanyforopengeneric(typeof(iconvertmodels<,>), assemblies); container.registermanyforopengeneric(typeof(imessagepublisher<>), assemblies);
dependency-injection inversion-of-control ioc-container bootstrapping
Comments
Post a Comment