Ace of Base vs Charli XCX - All That She Boom Claps (RMT) | Clean Bandit vs Galantis - I'd Rather Be You (RMT)
You've moved up on my notch-list. You have 1 notch
I have a black belt in Kung Flu.
Ik doe vooralsnog ook alles alleen in classes.
Tot ik laatst de MVC tutorial ben begonnen uit een boek ASP.NET MVC 4. Daarin begonnen ze ook ineens over interfaces en dependency injection. I was like WTFuzzle?
Interfaces zie ik overigens het nut nog wel van in en zal ik nog wel gaan gebruiken, maar DI gaat mij vooralsnog even te ver qua kennis.
[ Voor 8% gewijzigd door PdeBie op 25-11-2013 14:22 ]
Hmm.. ik ben ook nog niet echt thuis in DI, maar moet het wel leren.pdebie schreef op maandag 25 november 2013 @ 14:21:
haha herkenbaar.
Ik doe vooralsnog ook alles alleen in classes.
Tot ik laatst de MVC tutorial ben begonnen uit een boek ASP.NET MVC 4. Daarin begonnen ze ook ineens over interfaces en dependency injection. I was like WTFuzzle?
Interfaces zie ik overigens het nut nog wel van in en zal ik nog wel gaan gebruiken, maar DI gaat mij vooralsnog even te ver qua kennis.
Ik zit nu in de LOB-apps wereld van WinRT, en daar gebruiken wij Prism voor (MVVM-framework van Microsoft zelf). En Prism werkt vooral met DI.
Wordt DI eigenlijk gegeven op de Informatica opleidingen?HMS schreef op maandag 25 november 2013 @ 14:24:
Grappig, ik wil niet meer zonder DI. Ik vind het heerlijk om te gebruiken. En het geeft een leuke indicator als je code te veel gaat doen: je constructor krijgt heel veel dependencies/geinjecteerde objecten.
Op mijn opleiding (Informatica aan Saxion Enschede) komt het volgens mij alleen langs bij 1 specialisatie icm Spring.
[ Voor 26% gewijzigd door Ryur op 25-11-2013 14:26 ]
Dus vooralsnog is het een groot zwart gat waar ik in zit te staren. Zie nog niet wat de voordelen ervan zijn en wanneer je het wel/niet moet toepassen.
Wie weet zie ik het licht ooit nog wel eens
[ Voor 14% gewijzigd door PdeBie op 25-11-2013 14:30 ]
Voorbeeldje:
1
2
3
4
5
6
7
8
9
10
| public class MyHaxController : Controller { ICustomerRepository customers = DiContainer.Resolve<ICustomerRepository>(); [HttpGet] public ActionResult Index() { return View(customers.GetAll()); } } |
De implementatie van GetAll kan dan afhankelijk zijn van de gekozen repository: een TestCustomerRepository zal een statische lijst retourneren, een ProductionCustomerRepository zal queries uitvoeren op een database. De genoemde DiContainer kan dan weer a.d.h.v. configuratie bepalen welke ICustomerRepository moet worden geladen.
We are shaping the future
Komt mede ook doordat ik hier de enige ontwikkelaar binnen het bedrijf ben, waardoor ik niet echt iemand heb om mee te sparren en kennis uit te wisselen. Moet een heleboel op eigen houtje leren. Best lastig soms.
Dit boek deed mij het licht zien
Dat is een DI Container misbruiken als Service Locator, geen Dependency Injection.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| public class MyHaxController : Controller { private readonly ICustomerRepository customers; public MyHaxController(ICustomerRepository customers) { this.customers = customers; } [HttpGet] public ActionResult Index() { return View(customers.GetAll()); } } |
Sowieso probeer je met DI loose coupling voor elkaar te krijgen, dat bereik je zeker niet met een hardcoded verwijzing naar je DI container
Look, runners deal in discomfort. After you get past a certain point, that’s all there really is. There is no finesse here.
We are shaping the future
Zijn wel meer punten die je moet overwegen: http://blog.ploeh.dk/2010...eLocatorisanAnti-Pattern/Alex) schreef op maandag 25 november 2013 @ 14:35:
Dat is waar. Maar aan de andere kant, hoe vaak wissel je van DI container?
Maar in bepaalde gevallen is een Service Locator gewoon het makkelijkst.
Het gaat niet alleen om het wisselen; als je vanuit je code niet verwijst naar je DI-container maar constructor injection of (als het echt niet anders kan) property injection doet, is je code sowieso veel flexibeler. Je hoeft namelijk dan geen volledige DI-container te gebruiken, bijvoorbeeld in een unit test.Alex) schreef op maandag 25 november 2013 @ 14:35:
Dat is waar. Maar aan de andere kant, hoe vaak wissel je van DI container?
.oisyn: Échte programmeurs haten PHP met een passie. Ben jij soms geen echte programmeur?
Klopt, goed punt.Korben schreef op maandag 25 november 2013 @ 14:38:
[...]
Het gaat niet alleen om het wisselen; als je vanuit je code niet verwijst naar je DI-container maar constructor injection of (als het echt niet anders kan) property injection doet, is je code sowieso veel flexibeler. Je hoeft namelijk dan geen volledige DI-container te gebruiken, bijvoorbeeld in een unit test.
Mijn code was meer bedoeld om een idee te geven van hoe het werkt, niet hoe je het daadwerkelijk implementeert.
We are shaping the future
Dat is ook de manier waarop ik ook DI ken. Dat geklooi met die containers maakt het voor een beginner absoluut onleesbaar en onbegrijpelijk. Dat is iets wat mij bij veel boeken en tutorials tegenstond. Ze leggen vaak het principe niet echt uit maar mikken meteen DI containers en resolvers erin (het liefst ook nog 3rd party). Ik mis dat sowieso bij veel tutorials, ze gooien een oplossing naar binnen maar leggen vaak de basis niet uit en onderbouwen vaak de keus voor de oplossing ook niet echt (zodat je niet weet waarom er voor X is gekozen).kenneth schreef op maandag 25 november 2013 @ 14:33:
[...]
Dit boek deed mij het licht zien
[...]
Dat is een DI Container misbruiken als Service Locator, geen Dependency Injection.
C#:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 public class MyHaxController : Controller { private readonly ICustomerRepository customers; public MyHaxController(ICustomerRepository customers) { this.customers = customers; } [HttpGet] public ActionResult Index() { return View(customers.GetAll()); } }
Sowieso probeer je met DI loose coupling voor elkaar te krijgen, dat bereik je zeker niet met een hardcoded verwijzing naar je DI container
The #1 programmer excuse for legitimately slacking off: "My code's compiling"
Firesphere: Sommige mensen verdienen gewoon een High Five. In the Face. With a chair.
Nou ik zou het zeker geen basisprincipes noemen, want het wordt niet bij les 1 OO gegevenEddoH schreef op maandag 25 november 2013 @ 15:08:
Ik wist niet eens dat er een officiële term 'DI' voor bestond. Dit is toch gewoon 1 van de basisprincipes uit OO programmeren? Waar dienen interfaces anders voor?
Maar nu ik er iets langer ingedoken ben vind ik het wel een van de belangrijkste steunpunten van OO.
Herken me helemaal in je kritiek. "Druk op dit en dat knopje en nu heb je een RAID-array gebouwd, gefeliciteerd!!" en dan nog niet fatsoenlijk uitgelegd gekregen wat RAID is, wat de afwegingen zijn die je moet maken, wanneer je überhaupt RAID moet overwegen, enzovoort. Alleen de trucjes, niet de ideeën..Gertjan. schreef op maandag 25 november 2013 @ 15:06:
[...]
Dat is ook de manier waarop ik ook DI ken. Dat geklooi met die containers maakt het voor een beginner absoluut onleesbaar en onbegrijpelijk. Dat is iets wat mij bij veel boeken en tutorials tegenstond. Ze leggen vaak het principe niet echt uit maar mikken meteen DI containers en resolvers erin (het liefst ook nog 3rd party). Ik mis dat sowieso bij veel tutorials, ze gooien een oplossing naar binnen maar leggen vaak de basis niet uit en onderbouwen vaak de keus voor de oplossing ook niet echt (zodat je niet weet waarom er voor X is gekozen).
Dat boek van Seemann dat ik aanhaalde is een prettige uitzondering, pas in het laatste deel gaat hij diep in op een paar containers, in de eerste drie delen gaat het om de concepten, toepasbaarheid en patterns. Dat een DI container het leven soms(!) eenvoudiger maakt, is leuk maar secundair.
Look, runners deal in discomfort. After you get past a certain point, that’s all there really is. There is no finesse here.
DI is wel iets meer dan alleen maar tegen interfaces aan programmeren.EddoH schreef op maandag 25 november 2013 @ 15:08:
Ik wist niet eens dat er een officiële term 'DI' voor bestond. Dit is toch gewoon 1 van de basisprincipes uit OO programmeren? Waar dienen interfaces anders voor?
KloptCaelorum schreef op maandag 25 november 2013 @ 15:13:
[...]
DI is wel iets meer dan alleen maar tegen interfaces aan programmeren.
Als je een BLL laag bouwt is men snel geneigd om binnen die BLL aan te geven hoe de DAL gemaakt moet worden en worden de DAL implementaties daar dus ook aangemaakt, terwijl daar eigenlijk niet de verantwoordelijkheid hoort te leggen.
Als je op een andere plek de DAL maakt en deze vervolgens in de BLL injecteert is de BLL los te gebruiken zonder een harde afhankelijkheid van de DAL. Je zou dan je eigen DAL kunnen bouwen en deze dan inserten. Dit zorgt vaak voor een hogere testbaarheid van code en een lagere coupling van je lagen.
The #1 programmer excuse for legitimately slacking off: "My code's compiling"
Firesphere: Sommige mensen verdienen gewoon een High Five. In the Face. With a chair.
Bij basic basic OO kom je dingen tegen als het toepassen van de IComparable interface.
--------
Bij mijn thuisprojectje overgestapt op feature branches in git. Het helpt wel bij de focus om tegen jezelf te zeggen "ik werk nu in branch x en ik implementeer alleen feature x", ook al werk ik altijd in mijn eentje.
iOS developer
Met de nadruk op 'iets' dan, want óf ik ben retarded en snap het echt niet, óf het betekent echt alleen maar het doorgeven van instance variables (interfaces) aan een class door een ander component.Caelorum schreef op maandag 25 november 2013 @ 15:13:
[...]
DI is wel iets meer dan alleen maar tegen interfaces aan programmeren.
Ik ben nog op zoek naar het ongrijpbare en magische wat aan de term DI lijkt te hangen.
edit: ah! volgens mij ben ik niet de enige: http://www.jamesshore.com...njection-Demystified.html
[ Voor 11% gewijzigd door EddoH op 25-11-2013 15:40 ]
Maar wélke instances? DI is niet zo interessant, behalve wanneer je het combineert met een IoC container. Het voornaamste wat de IoC-container doet is de vraag 'welke instance' beantwoorden, en dat dat gecombineerd wordt met DI is bijna een bonus.EddoH schreef op maandag 25 november 2013 @ 15:34:
[...]
Met de nadruk op 'iets' dan, want óf ik ben retarded en snap het echt niet, óf het betekent echt alleen maar het doorgeven van instance variables (interfaces) aan een class door een ander component.
Ik ben nog op zoek naar het ongrijpbare en magische wat aan de term DI lijkt te hangen.
.oisyn: Échte programmeurs haten PHP met een passie. Ben jij soms geen echte programmeur?
Het gaat met name om de testbaarheid. Je wil bijvoorbeeld kunnen testen zonder een browsersessie te hebben of een database om alleen het component te testen.EddoH schreef op maandag 25 november 2013 @ 15:34:
[...]
Met de nadruk op 'iets' dan, want óf ik ben retarded en snap het echt niet, óf het betekent echt alleen maar het doorgeven van instance variables (interfaces) aan een class door een ander component.
Ik ben nog op zoek naar het ongrijpbare en magische wat aan de term DI lijkt te hangen.
Dit is een traditionele contstructor:
1
2
3
4
5
6
| public User() { // Get some stuff from HttpRequest // Go to database // Make user } |
Om deze code te testen moet je een database en een request hebben, kortom de hele boel opstarten en dan debuggen in je browser.
Dit doet IoC:
1
2
3
4
5
6
| public User(IHttpRequest request, IDataBase database) { // Get some stuff from IHttpRequest // Go to database via IDatabase // Make user } |
In je echte code roep je ze gewoon met de zelfde instance van HttpRequest en DataBase aan die je ook binnen de eerste constructor gebruikte. Echter in je tests geef je een gemockte HttpRequest op basis van IHttpRequest mee die een door jou vastgestelde waarde terug geeft. Zelfde geldt voor DataBase.
Nu test je alleen deze component en niet of je ORM en je browser sessie werkt.
Ander voordeel: je kunt het gedrag van je klasse veranderen alleen door hem met een andere implementatie van de interface die je in je constructor gedefinieerd hebt aan te roepen.
Je keert je klasse als het ware binnenste buiten waarbij heel veel functionaliteit uitgevoerd wordt door andere klasses die makkelijk inwisselbaar zijn.
En probeer je nu weer in te beelden dat die User IUser implementeert dus alle klasses die een User nodig hebben weer niet afhankelijk zijn van waar User weer van afhankelijk was.
Ik heb de laatste tijd meerdere malen meegemaakt dat ik implementaties heb gedaan in eerste instantie via Unit Tests me IoC en DI en dat ik het na twee dagen een keer voor het eerst in de browser opstartte en het gewoon meteen werkte.
----------------
Ik realiseer me dat ik DI en IoC weer eens een keer door elkaar gehaald heb....komt omdat ik ze precies op het zelfde moment geleerd heb en altijd tegelijk gebruik

Het voordeel van DI is dat je dus niet meer een hele rits aan interfaces aan een class meegeeft maar gewoon één keer het object registreert en het automagisch op alle plekken terecht komt waar je het nodig hebt.
Dit zou dus DI zijn:
1
2
3
4
5
6
| public User() { // Get some stuff from the registered IHttpRequest component // Go to database via the registered IDatabase component // Make user } |
Het voordeel is dat je niet meer overal Interfaces loopt rond te pompen in constructors maar gewoon een instance pakt als je hem nodig hebt en op dat moment ziet welke implementatie er geregistreerd is.
[ Voor 25% gewijzigd door BikkelZ op 25-11-2013 15:57 ]
iOS developer
:BikkelZ schreef op maandag 25 november 2013 @ 15:48:
Ik realiseer me dat ik DI en IoC weer eens een keer door elkaar gehaald heb....komt omdat ik ze precies op het zelfde moment geleerd heb en altijd tegelijk gebruikt
Bron: http://martinfowler.com/articles/injection.html (wat verder ook een prima artikel is voor IoC/DI uitleg)As a result I think we need a more specific name for this pattern. Inversion of Control is too generic a term, and thus people find it confusing. As a result with a lot of discussion with various IoC advocates we settled on the name Dependency Injection.
[ Voor 3% gewijzigd door IceM op 25-11-2013 15:55 ]
...
[ Voor 11% gewijzigd door EddoH op 25-11-2013 15:59 ]
Nee, je injecteert helemaal niets hier. Je voorbeeld met public User(IHttpRequest request, IDataBase database) is juist wel DI.BikkelZ schreef op maandag 25 november 2013 @ 15:48:
Dit zou dus DI zijn:
C#:
1 2 3 4 5 6 public User() { // Get some stuff from the registered IHttpRequest component // Go to database via the registered IDatabase component // Make user }
Met een DI container kan je er inderdaad voor zorgen dat het instantiëren met de juiste lifetime/dependencies/interceptors veel makkelijker gebeurt maar je zal alsnog je dependencies expliciet moeten maken. En dan is ctor injection het gebruikelijkst.
Interfaces rondpompen is juist een voordeel: het is gelijk duidelijk welke dependencies een class nodig heeft om te kunnen werken, je kan de class niet instantiëren zonder aan de dependencies te voldoen en op het moment dat je in je ctor een verwijzing naar vijf of meer interfaces hebt moet er een heel grote SRP-bel gaan rinkelen.Het voordeel is dat je niet meer overal Interfaces loopt rond te pompen in constructors maar gewoon een instance pakt als je hem nodig hebt en op dat moment ziet welke implementatie er geregistreerd is.
Look, runners deal in discomfort. After you get past a certain point, that’s all there really is. There is no finesse here.
I'm not a complete idiot. Some parts are missing.
.Gertjan.: Ik ben een zelfstandige alcoholist, dus ik bepaal zelf wel wanneer ik aan het bier ga!
Ik zie het zelf niet als zwakke kanten maar investeren in onderhoudbare code.
Look, runners deal in discomfort. After you get past a certain point, that’s all there really is. There is no finesse here.
Persoonlijk ben ik ook niet zo'n fan van classes die ineens ergens automagisch vandaan komen maar het ging even niet om mijn persoonlijke mening. Denk dat ik er wel ongeveer het zelfde over denk als jij.kenneth schreef op maandag 25 november 2013 @ 16:07:
Interfaces rondpompen is juist een voordeel: het is gelijk duidelijk welke dependencies een class nodig heeft om te kunnen werken, je kan de class niet instantiëren zonder aan de dependencies te voldoen en op het moment dat je in je ctor een verwijzing naar vijf of meer interfaces hebt moet er een heel grote SRP-bel gaan rinkelen.
iOS developer
Misschien een idee een ander bedrijf te zoeken? M.i. is niks belangrijker voor je eigen ontwikkeling dan het hebben van peers waaraan je je op kunt trekken.pdebie schreef op maandag 25 november 2013 @ 14:32:
Naja, daar gaat het bij mij dus al mis. Die termen als Repository etc. zijn nu nog abracadabra voor mij. Kom ze wel tegen in het boek, maar de echte know-how mis ik er nog van.
Komt mede ook doordat ik hier de enige ontwikkelaar binnen het bedrijf ben, waardoor ik niet echt iemand heb om mee te sparren en kennis uit te wisselen. Moet een heleboel op eigen houtje leren. Best lastig soms.
Er is niks "magisch" aan waar die instances vandaan komen. Dat wordt of door jou vastgelegd, of door het DI framework geresolved aan de hand van logische regels.BikkelZ schreef op maandag 25 november 2013 @ 17:07:
Persoonlijk ben ik ook niet zo'n fan van classes die ineens ergens automagisch vandaan komen maar het ging even niet om mijn persoonlijke mening. Denk dat ik er wel ongeveer het zelfde over denk als jij.
DI heeft gewoon voordelen waar je vooral profijt van hebt als je het testen goed aanpakt. Helaas gebeurt dat in de echte wereld meestal te slecht omdat het "te veel tijd kost".
[ Voor 33% gewijzigd door Hydra op 25-11-2013 17:22 ]
https://niels.nu
Van buitenaf dependencies laten zetten via een methode (setter injection) is al een flink stuk dynamischer (want je weet van tevoren niet óf en zo ja, wanneer die setter aangeroepen gaat worden) en dus complexer. Nog dynamischer (en complexer) wordt het, als dependencies tijdens de levensduur van een object ook weer kunnen verdwijnen, of wijzigen.
Met DI kan je zaken voor elkaar krijgen die je op een "traditionele" manier bijna niet voor elkaar krijgt. Bijvoorbeeld in een hoog-dynamisch systeem op basis van gebruikersconfiguratie services aan elkaar knopen (zonder een compile/deploy-slag).
Interfaces hebben inderdaad niet zoveel met DI van doen. Interfaces zijn in algemeen in OO-land belangrijk voor het specificeren een contract (API) waarvoor meerdere implementaties (kunnen) zijn. Interfaces helpen derhalve bij encapsulation en separation of concerns, twee belangrijke OO-principes. Hoe complexer je code, hoe belangrijker dergelijke principes worden. Niet geheel toevallig is dat ook waarom ze voor DI zo belangrijk zijn. Want ja: DI is zeer krachtig, maar het kan ook zeer complex zijn.
[ Voor 23% gewijzigd door Herko_ter_Horst op 25-11-2013 18:44 ]
"Any sufficiently advanced technology is indistinguishable from magic."