In un'architettura aziendale, dove viene utilizzato il Localizzatore di servizi più appropriato e perché?

7

Sto provando a implementare il pattern Locator del servizio. Nel diagramma seguente sono i miei riferimenti tra progetti (progetti .net), ogni riquadro rappresenta un progetto.

Le frecce indicano le dipendenze.

Sto chiedendo se questa è una corretta implementazione di questo pattern o c'è un modo migliore?

    
posta user1653400 28.07.2016 - 01:32
fonte

2 risposte

3

I am asking if this is a correct implementation of this pattern or is there a better way?

Non esattamente. Il localizzatore di servizi, in uno scenario ideale, non dipende da alcuna interfaccia: è solo un contenitore / mappa / fabbrica stupido. Qualcosa (riflessione, codifica manuale, ereditarietà, qualche forma serializzata, ecc.) Lo popola, e poi quando i consumatori chiedono un'istanza che soddisfi alcune interfacce arbitrarie, il localizzatore di servizi lo fornisce. A seconda di come è implementato, non dipende nemmeno dai dati - i suoi consumatori dicono dove andare.

In an enterprise architecture, where is Service Locator most appropriately used, and why?

Tutto ciò detto, il localizzatore di servizi è comunemente visto come un anti-pattern dal momento che il contratto che fornisce (chiedi un'interfaccia arbitraria, ti do un'istanza che lo soddisfa) è molto ampio . Tende ad essere un oggetto di Dio. Tende ad essere un po 'fragile dal momento che gli errori in uso si mostrano solo al runtime.

Questi aspetti negativi sono veri, ma l'anti-pattern implica che produce sempre cattiveria quando viene utilizzato. Questo non è il caso della mia esperienza.

I localizzatori di servizio sono utili quando si hanno molti componenti dinamici che devono essere risolti in fase di esecuzione - componenti che variano a seconda del contesto in cui si sta lavorando. Ad esempio, l'ho visto usato per emulare una varietà di dispositivi hardware, ciascuno con la propria configurazione e capacità. È stato altrettanto facile da testare come contenitori IoC, ha avuto errori di runtime simili, ma ha fornito la flessibilità necessaria che i contenitori IoC non potevano.

Ma questo tipo di scenario è estremamente raro. In generale, avere quel tipo di ricerca di tipo arbitrario non vale il costo.

    
risposta data 13.08.2016 - 00:38
fonte
3

So che la domanda riguarda Service Locator, ma

is there a better way?

Sì, permettimi di suggerire un design migliore per la tua soluzione.

Prima di tutto ti suggerisco di usare Dependency Injection tramite Constructor + DI Container invece del pattern Sevice Locator. Service Locator ha un numero di aspetti negativi. Per farla breve:

  • Il tuo codice richiede un riferimento alla classe / progetto Service Locator;
  • È più difficile testare l'unità;
  • Durante la modifica / aggiunta di nuove dipendenze è facile interrompere / dimenticare di aggiungere qualcosa nel localizzatore di servizi. In altre parole - più difficile da mantenere.

Ecco di più su Anti-pattern Locator di servizio .

Design alternativo:

Funzionidialtolivello:

  1. IltuoBusinessLayer(BL)-contieneidatiaziendalielalogica,ovveroentitàeservizi-nondipendedalcodicedilivelloinferiore(comel'infrastrutturaol'accessoaidati).Èunacosainsé,indipendentedalcodiceinfrastruttura/DAL.
  2. Contrattidiaccessoaidati(DAC)-Interfacciadelrepositorynell'esempio-consideratocomepartediBLecontenentesoloastrazioni(interfacce)perillivellodiaccessoaidatiutilizzatoinBL.PuòfarpartedelprogettoBLonelproprioprogetto.SipregadinotarechenoncisonofrecceinuscitadallacasellaBL/DAC.Ciòcorrispondea Principio di inversione delle dipendenze .
  3. Accesso ai dati (DA) - Fa riferimento a Business Logic e contiene un'implementazione concreta delle interfacce dai contratti di accesso ai dati per la tua archiviazione dati specifica.
  4. Composition Root - è un progetto speciale che fa riferimento a tutti gli altri progetti e compone il contenitore DI. Puoi usare qualsiasi contenitore DI popolare come Ninject, Autofac, Unity ...
  5. La radice dell'applicazione - ad esempio l'app ASP.Net - dovrebbe inizializzare il contenitore DI all'avvio dell'applicazione e registrare il contenitore come Dependency Resolver predefinito.
  6. Quindi ovunque nel tuo codice dovresti usare Iniezione delle dipendenze tramite Costruttore

I vantaggi:

  • Le classi sono liberamente accoppiate.
  • Test dell'unità facile
  • La logica aziendale è riutilizzabile: puoi facilmente estrarla e utilizzarla per l'app per dispositivi mobili, ad esempio, con accesso ai dati e interfaccia utente diversi.
  • La modifica / aggiunta delle dipendenze richiede la modifica del costruttore, che fornisce un feedback sugli errori in fase di compilazione.

Btw, ecco un eccellente libro sull'argomento: Iniezione delle dipendenze in .NET

    
risposta data 12.08.2016 - 23:39
fonte

Leggi altre domande sui tag