Ciao a tutti,da ieri pomeriggio sto sbattendo la testa con il seguente problema...
Contesto: applicazione web che consente l'avvio, in modalità asincrona, di procedure (Job) verso un sistema esterno. Uso Ninject come IoC provider.
L'interazione con il sistema esterno avviene tramite un SKD proprietario. Ogni interazione con il sistema esterno deve essere effettuata all'interno di una UnitOfWork, che può essere "attivata" in due modalità:
Io ho i tutti i miei bei repository, che agganciati alla UoW, mi consentono di recuperare i dati di cui ho bisogno dal sistema esterno, e salvare le modifiche ad essi apportate.
Quando l'utente accede alla mia applicazione, deve poter vedere una maschera contenente una serie di campi alimentati con tutte e sole le entità di tipo Foo, lette dal sistema esterno, su cui lui ha visibilità. Tramite questa maschera, può scegliere i parametri di avvio del Job e lanciarlo. Il job sarà avviato in un thread secondario (tramite un Task); per funzionare correttamente, il job ha bisogno di poter "vedere" tutti i dati presenti nel sistema esterno.
Avrei dunque bisogno che:
(nel primo caso, avrei bisogno che venisse creata una nuova sessione ad ogni richiesta HTTP. Nel secondo caso, deve essere creata una nuova sessione per ogni run del job).
Come posso fare? Qualche idea?
Grazie,neronotte
Ciao Mauro,
effettivamente nel descrivere la soluzione ho "semplificato" un po' le cose: attualmente i repository ereditano già da un session provider fatto più o meno così:
public interface ISessionProvider{ ISession GetSession();} la classe base, generica, Repository<T> espone una proprietà protected Session:
public abstract class Repository<T> : IRepository<T>{... protected ISession Session { get { return this.sessionProvider.GetSession(); } }...}
se utilizzassi il sessionProvider che mi hai consigliato, non violerei il SRP? Intendo... a quel punto diventerebbe compito del repository decidere quale tipo di sessione utilizzare, o sbaglio?
E se sia il job che la pagina utilizzassero lo stesso "tipo" di repository? (Entrambi avranno bisogno dello UserRepository, per dirne una...)
Grazie :)neronotte
c'ho provato... il problema resta nella gestione del lifecycle delle diverse session: la sessione aperta in modalità 1 deve durare quanto la request, mentre la sessione in modalità 2 deve durare quanto un run del job. I provider, a quanto sembra dalle prove che ho fatto, vengono "valutati" soltanto alla prima richiesta dell'oggetto "provisionato" all'interno dello scope definito in fase di configurazione (l'HttpContext corrente, nel caso della modalità 1), dopodichè ninject "cacha" il valore ottenuto dal provider agganciandolo in qualche modo all'oggetto che definisce lo scope, e continua a restituire la medesima istanza finquando questo non viene processato dal garbage collector.
Temo che l'unica via per uscirne sia avere due Kernel distinti, uno per il modulo "Web", e l'altro per il modulo di processamento dei job...
...e la cosa non mi piace per niente.
Altre idee?