Anche se il concetto di IoC non mi è estraneo, sono nuovo di Unity e ho difficoltà a connettere i punti metaforici, per così dire.
Nel nostro progetto abbiamo una libreria di classi per la logica, quindi diverse librerie di classi con repository che implementano interfacce comuni (forniscono accesso e consentono operazioni CRUD su diverse origini dati). Infine, tutto questo viene utilizzato insieme in un sito Web MVC o in un sito di SharePoint.
Volevamo implementare Unity per mantenere una singola configurazione e migliorare il tutto.
Ma ... ci sono alcuni problemi di progettazione che sto affrontando. Ad esempio, il sito Web MVC, per quanto riguarda la comunicazione con il database SQL sottostante, può disporre di tutto ciò che deve essere specificato nella sezione di configurazione per il contenitore Unity. Tuttavia, detto sito Web deve anche collegarsi occasionalmente con SharePoint ... per creare un repository SharePoint, ho bisogno di creare un oggetto SPWeb
e passarlo al costruttore del repository.
POSSO farlo usando ParameterOverride
quando risolvo il tipo, ma questo non ... mi sembra giusto. Ci sono casi in cui un numero maggiore di parametri deve essere sovrascritto in questo modo; per risolvere una classe logica ho bisogno di passare repository, che a loro volta vengono risolti passando un oggetto SPWeb
creato manualmente ... Quando ciò accade sembra che non stia più seguendo un pattern IoC. Il kicker è che non posso avere l'oggetto SPWeb
definito nel contenitore Unity!
Esiste un modello (un esempio pratico sarebbe superbo) dove viene usato Unity ma determinati valori vengono passati al contenitore durante la risoluzione dei tipi, senza la necessità di usare ParameterOverride
?
Modifica
Credo di dover fornire un esempio più specifico del perché ParameterOverride
è un problema. Di seguito è riportato un frammento di codice utilizzato da un processo timer di SharePoint. Il lavoro in questione sincronizza alcuni dati tra SharePoint e SQL, quindi richiede due diversi repository che implementano la stessa interfaccia. Poiché il codice viene eseguito da SharePoint, non può accedere a una configurazione globale definita DataContext
(EntityFramework, code-first) poiché non esiste un file web.config
da cui leggere la stringa di connessione. Inoltre, a causa della stranezza che è SharePoint, non riesco a "ottenere" l'attuale oggetto SPWeb
, e invece ho bisogno di crearlo al volo.
Il risultato finale è una tonnellata su using
e molti parametri devono essere sovrascritti quando si usa Resolve
. Inoltre, la necessità di passare il parametro NAME come una stringa renderebbe questo codice molto difficile per chiunque altro: questa informazione non è nota dall'interfaccia.
public override void Execute(Guid targetInstanceId)
{
var siteUrl = Properties["Site"] as string;
var sqlConnection = Properties["SQL"] as string;
if (String.IsNullOrEmpty(siteUrl))
throw new ArgumentNullException("Site URL is missing.");
if (String.IsNullOrEmpty(sqlConnection))
throw new ArgumentNullException("SQL connection string is missing.");
using (var site = new SPSite(siteUrl, SPUserToken.SystemAccount))
using (var web = site.OpenWeb())
using (var spPollRepository = Configuration.ServiceLocator.SharePointContainer.Container.Resolve<IPollRepository>(new ParameterOverride("web", web)))
using (var ctx = Configuration.ServiceLocator.SharePointContainer.Container.Resolve<Repositories.PollsDataContext>(Configuration.ServiceLocator.SqlNamedRegistration, new ParameterOverride("nameOrConnectionString", sqlConnection), new ParameterOverride("initialize", false)))
using (var sqlPollRepository = Configuration.ServiceLocator.SharePointContainer.Container.Resolve<IPollRepository>(Configuration.ServiceLocator.SqlNamedRegistration, new ParameterOverride("ctx", ctx)))
{
IPollsSyncLogic logic = Configuration.ServiceLocator.SharePointContainer.Container.Resolve<Logic.IPollsSyncLogic>(new ParameterOverride("sqlRepository", sqlPollRepository), new ParameterOverride("spRepository", spPollRepository));
logic.SyncPolls();
}
}
C'è una grande possibilità che sto usando Unity ... sbagliato. O che qualche altra definizione fondamentale è stata confusa. Spero che questo chiarisca ogni confusione sulla questione.