7

Con le normali pagine ASP.NET MVC, il repository viene passato al costruttore del controllo. Quindi i test possono istanziare il controller passando in un deposito fittizio.Come utilizzare l'integrazione delle dipendenze e il pattern del repository con i servizi Web ASP.NET?

Come posso fare questo con i servizi web? Il problema che vedo è che non abbiamo l'equivalente di ControllerBuilder.SetControllerFactory.

Quali sono le migliori pratiche per ottenere il mio framework IoC (Castle) per istanziare il mio servizio Web con l'implementazione corretta del repository?

Ho pensato che potrebbe esserci un modo per estendere HttpHandler e cambiare il modo in cui il servizio web è effettivamente istanziato. Credo che questo sia il modo in cui il framework MVC lo fa.

+0

Quale tecnologia stai usando per implementare i propri servizi web? Servizi Web ASP.NET o Windows Communication Foundation? –

+0

Servizi Web ASP.NET. Tuttavia, dopo aver letto la risposta di jrista, penso che valga la pena di esaminare la WCF se davvero voglio iniettare dipendenze. Sto considerando di avere solo due costruttori - uno che prende il repository come parametri (i test chiameranno questo) e uno predefinito che eseguirà un hard code: questo (nuovo IRepository) e verrà chiamato dal framework ASP.NET. –

risposta

1

Credo che si sta cercando per il Fondo Castello di Windsor WCF integrazione. Fornisce un'implementazione ServiceHost che riprende il processo di costruzione delle implementazioni del servizio, utilizzando il CIO di Windsor.È possibile iniettare le dipendenze come qualsiasi altro CIO app che utilizzano questa struttura, e abbastanza comoda, parte del progetto Castello la sua:

http://www.castleproject.org/container/facilities/trunk/wcf/index.html

Se la versione Castello Progetto non fa quello che avete bisogno di fare, ho la mia struttura che ho creato per fare la stessa cosa per Windsor prima di trovare la versione del progetto Castle. Entrambi fanno generalmente la stessa cosa, ma entrambi affrontano il problema in modo leggermente diverso.

+0

Suppongo che la risposta sia "non è possibile utilizzare il constructor injection con servizi Web ASP.NET", quindi utilizzare BuildUp (this) o usare WCF con castle. –

+1

In realtà, dovresti essere in grado di utilizzare Castle Windsor con i servizi di stile ASMX (se questo è ciò che intendi). Ho pensato che stavi chiedendo di WCF, ma non vedo perché non potresti integrare Windsor nella pipeline ASMX. Probabilmente non è così facile come con WCF, ma non dovrebbe essere impossibile. – jrista

+0

@jrista poiché ServiceHost non è consentito nel file asmx, hai qualche esempio su come implementare DI per i servizi asmx? – Nobody

2

Questa è una buona domanda. Ho lo stesso problema. Penso che se stai creando servizi web usando file .asmx, è impossibile usare l'iniezione del costruttore. Se stavi usando WCF per implementare il servizio web, allora penso che sia possibile.

Nel mio servizio Web .asmx, il contenitore DI imposta le dipendenze impostando le proprietà. Siccome la mia applicazione è anche un'applicazione web asp.net, è come devo farlo, perché non posso nemmeno usare l'iniezione del costruttore sui moduli web. Ma sto usando StructureMap, e ha una funzione BuildUp che può impostare le proprietà di un oggetto già creato. Non pulito come un'iniezione del costruttore, ma un buon compromesso.

Ma i servizi Web si differenziano dai moduli Web, perché posso posizionare l'accumulo al di fuori del modulo Web, nell'evento Application_PostMapRequestHandler. Ma non ho scoperto un evento che viene attivato dopo la creazione della classe del servizio web. Così nel costruttore del mio servizio web, ho il seguente codice

ObjectFactory.BuildUp(this); 

E questo è un modello anti. Una classe inizializzata da un contenitore DI non dovrebbe conoscere il contenitore DI stesso. Ma non ho ancora trovato una soluzione migliore.

0

Definire una classe base e utilizzare l'iniezione di proprietà in tale posizione. Pete l'ha già detto, ma tu dovresti fare: ObjectFactory.BuildUp (this);

La differenza è che lo inserisco su una classe base per i servizi Web, quindi è "automatico" per le specifiche implementazioni.

In questo modo è una riga, quindi non mi interessa se non si ha la necessità esplicita di passare i contenitori DI in fase di esecuzione (improbabile). Se è ancora necessario, sposta la chiamata in una classe separata che utilizzerà il contenitore DI specifico.

0

C'è qualche ragione per cui non è possibile creare una classe personalizzata con il costruttore desiderato, quindi istanziare un oggetto di quella classe in asmx, quindi delegare tutte le azioni a quell'oggetto?

genere creo questi tipi di oggetti come questo:

var o = CustomClass.Create(); 

public class CustomClass 
{ 
    public static CustomClass Create() 
    { 
    return IoC.Resolve<CustomClass>(); 
    } 
} 

public static class IoC 
{ 
    public T Resolve<T>() 
    { 
    return yourStaticReferenceToPreferredContainer.Resolve<T>(); 
    } 
} 
Problemi correlati