Come gestire gli oggetti di contesto in un'applicazione multi-tenant?

0

Sto costruendo un'API Web che interfaccia SharePoint (un servizio Web esterno). Per ottenere la connessione al servizio esterno ho bisogno di creare istanze di ClientContext con qualche tipo di token.

Per questo ho creato un'interfaccia chiamata IClientContextFactory:

interface IClientContextFactory
{
    Create ClientContext(string siteUrl)
}

Ho creato un'implementazione HttpClientContextFactory che crea oggetti usando le attestazioni dell'attuale HttpRequest che viene iniettata in fabbrica. Sulla base delle affermazioni, so a quale tenant si applica ClientContext.

Funziona bene con la web api, ma per quanto riguarda le mie applicazioni console di supporto che non hanno un contesto utente? Devo inviare l'id titolare con ogni messaggio a questi che a sua volta significa che l'interfaccia IClientContextFactory non funziona. Per questo ho creato IAppClientContextFactory:

interface IAppClientContextFactory
{
   Create(Guid tenantId, string siteUrl);
}

Ciò risulta imbarazzante perché ora qualsiasi implementazione che dipende da IClientContextFactory è inutile nelle applicazioni della console poiché non posso implementarla senza un contesto utente.

Potrei aggiungere Create(Guid tenantId, string siteUrl) a IClientContextFactory ma questo violerebbe Liskov dal momento che Create(string siteUrl) genererebbe una NotImplementedException nelle applicazioni della console.

C'è un modo migliore per farlo? Sto prendendo l'approccio sbagliato a questo? Lo sto facendo anche correttamente e non dovrei preoccuparmi affatto? In particolare, è difficile per i nuovi sviluppatori dover capire quali dipendenze devono essere registrate nel contenitore IoC per la loro applicazione particolare.

    
posta Gabriel Smoljár 02.09.2016 - 17:02
fonte

2 risposte

2

Come vedo, il tuo problema è che provi a introdurre i dettagli di implementazione del servizio web (Context) come astrazione.

"Leak astrazione" il nome per questo problema.

I consumatori del servizio web non hanno bisogno di sapere come si invia un messaggio. I consumatori devono solo fornire i dati richiesti (argomenti) e ottenere il risultato come valore di ritorno.

public interface IWebService
{
    ResultType GetData(string credentials);
}

Quindi per l'applicazione web e per l'applicazione console è possibile implementarli in modo diverso.

O usi la stessa implementazione, ma il modo in cui ottieni gli argomenti richiesti sarà diverso nell'applicazione web e console

    
risposta data 07.08.2017 - 22:15
fonte
0

L'approccio migliore sarebbe avere un provider di identità collegabile che varierà in base al tipo di applicazione che si intende consumare.

Ad esempio, crea un'interfaccia IUserContext che avrà proprietà come ID utente, ID titolare ecc. L'applicazione web con uso di qualcosa come WebUserContextProvider:IUserContext . Allo stesso modo, i servizi o i lavori avranno come JobUserContextProvider: IUserContext Queste implementazioni verranno impostate tramite un'unità DI simile o autofac

HTH

    
risposta data 07.06.2017 - 19:01
fonte

Leggi altre domande sui tag