Iniezione costruttore vs. IocFactory

2

Oggi al lavoro un collega e ho avuto una discussione su quanto segue:

Fondamentalmente abbiamo un motore di regole che funziona nel modo seguente:

RuleExecutor

  • Ottiene tutte le regole da eseguire nel costruttore come public RuleExecutor(ICollection<IRule> rulesToExecute) { ... }

  • Esegue tutte le regole chiamando rule.ApplyRule(); per ogni rulesToExecute

Regole

  • Fornisci il metodo ApplyRule (); che esegue la regola

Ora vogliamo che RuleExecutor sia eseguito in un cron job.

Abbiamo discusso su come recuperare un'istanza di RuleExecutor.

Penso che il "modo corretto" sia tramite l'iniezione del costruttore

public RuleCronJob(IRuleExecutor ruleExecutor) { ... }

Il mio collega desidera utilizzare un "IocFactory" che abbia un metodo statico GetInstance < & gt ;. Quindi nel "metodo di esecuzione" del lavoro cron farebbe qualcosa come var ruleExecutor = IocFactory.GetInstance<IRuleExecutor>();

public static TType GetInstance<TType>(params Tuple<string, object>[] constructorParameters)
    {
        if (constructorParameters.Any())
        {
            var constructorArgs = new Collection<ConstructorArgument>();
            foreach (var parameter in constructorParameters)
            {
                constructorArgs.Add(new ConstructorArgument(parameter.Item1, parameter.Item2, true));
            }

            return Kernel.Value.Get<TType>(constructorArgs.Cast<IParameter>().ToArray());
        }

        return Kernel.Value.Get<TType>();
    }

Il kernel è un kernel standard di Ninject.

Penso che l'iniezione del costruttore sia migliore perché consente test più semplici (beffa) ecc. ma non posso convincerlo a usarlo perché pensa che l'IocFactory "funzioni pure così perché non usarlo" ...

  • Quali sarebbero alcuni argomenti per convincerlo a utilizzare l'iniezione del costruttore invece di IocFactory?
posta xeraphim 17.06.2015 - 14:42
fonte

2 risposte

5

Bene, per cominciare, la IOCFactory, o meglio il modo in cui l'hai descritta, è una bugia dal volto audace, perché non implica inversione di controllo. Se continui a chiamare getInstance (), dovresti almeno rinominare il presunto IOCFactory.

Come Ben Aaronson ha sottolineato, un container senza inversione di controllo è solo un Localizzatore di servizi. Molto è stato scritto su Dependency Injection vs. Service Locator, più di dieci anni fa di Martin Fowler sul suo blog, o cinque anni fa su StackOverflow: link

    
risposta data 17.06.2015 - 16:10
fonte
1

but I couln't convince him to use it because he thinks that the IocFactory "works as well so why not use it"...

Perché è più complicato?

Piuttosto per definizione, il codice che sta facendo più cose ha più cose che possono andare storte. Per i contenitori IoC, ciò significa spesso lotti di cose sotto le copertine per scoprire le varie dipendenze, risolverle, iniettarle ... I contenitori IoC sono l'opzione nucleare per l'iniezione di dipendenza. Risolveranno il tuo problema, ma sono quasi sempre eccessivi, e lasceranno incerti effetti indesiderati a prescindere.

    
risposta data 17.06.2015 - 15:11
fonte