Come faccio a racchiudere un servizio in modo che sia più semplice

10

Abbiamo una dipendenza da un servizio di terze parti che espone un'interfaccia gigantesca di cui abbiamo solo bisogno come 3 metodi. Inoltre, l'interfaccia cambia frequentemente ...

Ho deciso di avvolgere l'interfaccia in una classe del nostro progetto e di esporre solo i metodi di cui abbiamo bisogno.

Ma non sono sicuro di come gestire i valori di ritorno ... L'interfaccia restituisce un oggetto di tipo Storage . Abbiamo internamente un tipo StorageModel che è la nostra rappresentazione interna di Storage .

Cosa vorresti restituire nel mapper: Storage o StorageModel ? Abbiamo un DataService StorageService che ottiene una dipendenza dal wrapper iniettato.

Attualmente lo faccio fondamentalmente in questo modo:

public class StorageService 
{
    private readonly IExternalStorageWrapper externalStorageWrapper;

    public StorageService(IExternalStorageWrapper externalStorageWrapper)
    {
        this.externalStorageWrapper = externalStorageWrapper;
    }

    public StorageModel GetStorage(int storageId)
    {
        return this.externalStorageWrapper.GetStorage(storageId).ConvertToStorageModel();
    }
}

public class ExternalStorageWrapper : IExternalStorageWrapper
{
    public Storage GetStorage(int storageId)
    {
        using(var ext = new ExternalStorage())
        {
            return ext.GetStorage(storageId);
        }
    }
}

Che cosa diresti:

  • È buono come sopra, che il wrapper restituisca l'oggetto Storage esterno e il% interno interno di co_de restituisca il% interno% di co_de?
  • Oppure restituiresti già StorageService nel wrapper?
posta xeraphim 16.02.2018 - 08:03
fonte

4 risposte

11

Nel mio caso, il wrapper dovrebbe occuparsi di tutte le cose relative alla libreria esterna. Ciò significa che l'interfaccia pubblica del wrapper non deve nominare alcun tipo esterno.

La mappatura di tipi esterni ai rispettivi tipi di applicazione fa parte dei compiti del wrapper. Se questa non è un'operazione banale, allora puoi usare i vari strumenti disponibili per scomporre il problema, ad es. iniettare un oggetto traduttore. Tuttavia, il traduttore deve comunque far parte del tuo modulo wrapper e nessun'altra parte della tua applicazione può dipendere da esso.

In questo modo, il resto della tua applicazione è completamente immune non solo ai cambiamenti nella libreria, ma anche alle sostituzioni della libreria per un'altra.

    
risposta data 16.02.2018 - 08:18
fonte
3

I've decided to wrap the interface in a class in our project and only expose the methods that we need.

Va bene. Questo è anche noto come Adapter .

Scegli il pattern Adapter , quindi lo scopo qui è trasformare una interfaccia (modello di libreria) in un altro (modello di dominio). Pertanto, se qualcosa del primo raggiunge il modello di dominio, l'adattatore non riesce a raggiungere lo scopo .

Secondo gli argomenti precedenti, l'adattatore dovrebbe restituire StorageModel .

In definitiva, il tuo dominio "parla" una lingua specifica, in cui Storage è un straniero .

But I'm unsure how I should handle the return values...

La chiave qui è sapere per quale motivo sei avvolgere / adattare la libreria .

Adattatore, Decoratore, Modelli di facciate potrebbero avere somiglianze ma sono abbastanza diversi. Tanto diversi quanto i problemi che risolvono.

Detto questo, potresti essere interessato anche a:

risposta data 16.02.2018 - 23:46
fonte
1

Non è possibile racchiudere in modo efficace una libreria duplicandola.

Quello che dovresti avvolgere è l'uso della libreria e ciò significa non esporsi oggetti, in questo caso Archiviazione. Non provare a duplicarli.

Usa la biblioteca, ma tienila contenuta. Quindi, nel tuo caso, supponendo che tu usi lo StorageService per archiviare le cose dovresti tenerlo nei repository

MyPocoObjectRepo
    MyPocoObject GetObject(string id);

dove MyPocoObject è interamente dati e logica aziendale. Non una duplicazione di Storage o di un DataReader o altro

    
risposta data 16.02.2018 - 09:35
fonte
0

La risposta è che dipende dalla necessità o meno di accedere a Storage direttamente da una classe che non è StorageModel .

Se hai intenzione di racchiudere la libreria, ha senso avvolgere anche l'oggetto da essa restituito per consentire future modifiche alla bozza effettuate dalla libreria in futuro. Tuttavia, se è necessario utilizzare direttamente Storage , significa che potrebbe essere necessario restituire Storage in base alla situazione. Un argomento potrebbe essere detto per obbligare l'utilizzo di Storage qui per essere StorageModel , poiché probabilmente vorrai rimanere coerente in tutto il tuo programma.

Raccomando vivamente di avvolgere sia l'interfaccia che l'oggetto restituito se non lo stai già facendo, anche se di nuovo, che ha senso solo se stai usando StorageModel per tutto il tuo programma e non per Storage .

    
risposta data 16.02.2018 - 09:21
fonte