Esecuzione di istanze separate
Sembra che tu stia gestendo istanze multiple di un servizio logicamente separate (una per azienda). Fondamentalmente, la tua domanda riguarda il modo migliore per garantire che questo isolamento venga mantenuto.
Attualmente, l'isolamento viene raggiunto all'interno dell'applicazione. Come ha sottolineato @MetaFight, questo ha il rischio che un bug nel tuo codice possa romperlo. I candidati evidenti sono cose che vengono tenute in memoria tra le richieste, ad es. dati memorizzati nella cache.
Perché diverse istanze (logiche) del tuo servizio non sembrano aver bisogno di interagire - ad esempio i dati della società A non influenzano i dati della società B - potresti prendere in considerazione la possibilità di spostare l'isolamento dalla tua applicazione e trattarla separatamente. (Di nuovo, vedi i commenti di @ MetaFight).
Ciò riduce la complessità dell'applicazione, al costo di aumentare la complessità delle distribuzioni. Lo stato può ancora essere trapelato in questo scenario, ad es. se si commette un errore di configurazione, collegare il servizio della società A al database della società B. Tuttavia, ora hai separato questo problema dalla logica della tua applicazione e puoi utilizzare tutti gli strumenti DevOps disponibili per gestire separatamente questo problema (comune).
A partire dallo stato corrente
Tuttavia, ritengo che la tua applicazione sia già implementata, quindi gli approcci di commutazione potrebbero non essere (immediatamente) un'opzione. In tal caso, almeno la logica del dominio dovrebbe ignorare il fatto che ci sono più società e non dovrebbe mantenere lo stato tra le richieste. Forse puoi modulare la tua applicazione seguendo le seguenti linee:
-
Selettore database
Trasforma un URL in un oggetto accessor del database. Fai tutte le richieste attraverso questo oggetto. Fai lo stesso per tutto il resto che dipende dalla compagnia.
-
Funzionalità di business
Calcola dati, invia e-mail, ecc. Utilizza un oggetto accessor del database dove necessario. Questo modulo non sa che ci sono più aziende. Meglio ancora, inserisci l'accesso DB in un livello a sé stante e fornisci solo i dati alla tua logica aziendale.
-
Gestore richieste
Riceve i dati della richiesta, ottiene il corretto accesso al database e lo fornisce al livello aziendale.
Questa architettura può essere notevolmente migliorata, ma questo è al di fuori della portata della domanda. (Dai un'occhiata a qui , per esempio).
Una volta che l'applicazione ha questa forma, è molto più semplice andare al passo successivo: è sufficiente che il selettore del database fornisca sempre la stessa connessione al database, che può essere letta da un file di configurazione. E poi ripeti questa configurazione tutte le volte che ti servono.
Esempio di implementazione
Questo è un esempio molto semplice. Ancora, ci sono molti modi per migliorarlo, ma questo non è specificamente correlato alla domanda. Ho mantenuto il DB fuori dalla logica di business (invio di mail) qui. Se questo è un passo troppo grande all'inizio, puoi passare l'istanza IDatabase
a WelcomeMailSender
e poi andare da lì.
interface IDatabase
{
MailData GetMailDataForUser(int userId);
}
interface IDatabaseSelector
{
IDatabase GetFromUrl(Url url);
}
class SendWelcomeMailRequestHandler
{
private readonly IDatabaseSelector dbSelector; // inject via constructor
private readonly WelcomeMailSender sender; // inject via constructor
ResponseData HandleRequest(RequestData req)
{
var db = dbSelector.GetFromUrl(req.RequestUrl);
var data = db.GetMailDataForUser(req.UserId);
var success = sender.SendWelcomeMail(data);
return new ResponseData() { Success = success };
}
}
class WelcomeMailSender
{
bool SendWelcomeMail(MailData data)
{
// do all the mail-sending stuff
}
}