2010-04-05 5 views
6

Ho una pagina Web Form ASP.NET che il presentatore deve compilare con i controlli. Questa interazione è alquanto sensibile al ciclo di vita della pagina e mi chiedevo se c'è un trucco, che non conosco.Disaccoppiamento della vista, presentazione e moduli Web ASP.NET

Voglio essere pratico per tutto ciò ma non compromettere la testabilità.

Attualmente ho questo:

public interface ISomeContract 
{ 
    void InstantiateIn(System.Web.UI.Control container); 
} 

Questo contratto ha una dipendenza System.Web.UI.Control e ho bisogno che, per essere in grado di fare le cose con il Web ASP.NET Forms modello di programmazione. Ma né la visualizzazione né il relatore possono avere conoscenze sui controlli del server ASP.NET.

Come aggirare questo? Come posso lavorare con il modello di programmazione Web Form ASP.NET nelle mie viste concrete senza utilizzare una dipendenza System.Web.UI.Control nei miei assembly del contratto?

Per chiarire un po ', questo tipo di interfaccia riguarda esclusivamente la composizione dell'interfaccia utente (utilizzando MEF). È conosciuto attraverso il framework, ma in realtà è chiamato solo all'interno della vista concreta. La vista concreta è ancora l'unica cosa che sa di Web Form ASP.NET. Tuttavia, quei metodi pubblici che dicono InstantiateIn(System.Web.UI.Control) esistono nei miei assembly di contratto e ciò implica una dipendenza da Web Form di ASP.NET.

Ho pensato a qualche meccanismo di doppia spedizione o addirittura a un modello di visitatore per cercare di aggirare questo problema, ma non so ancora in quale direzione voglio andare e mi piacerebbe davvero un input sull'argomento.

+0

Perché la visualizzazione e il relatore non possono conoscere i controlli server ASP.NET? –

+0

@ Testabilità kirk? non sarà difficile (dannatamente vicino impossibile) deridere queste cose? –

+0

Potresti rispondere http://stackoverflow.com/questions/8851933/event-bubbling-and-mvp-asp-net? – Lijo

risposta

0

Un modo per separare il contratto dal controllo Web è disporre di uno scrittore separato che gestisca il recupero delle informazioni da ISomeContract e lo inserisca nel contenitore di controllo. Questo potrebbe risiedere in un assembly che fa riferimento sia all'assembly del contratto che a System.Web.

+0

Potresti fare un esempio concreto? –

0

Ho letto di tecniche agili, tdd, unit test, solidi schemi di progettazione e mi sentivo completamente impotente per colmare il divario tra questa meravigliosa teoria e le webform di asp.net.

Ho avuto un altro andare a cercare di trovare una soluzione a questo problema prima di oggi e ho trovato questo articolo:

Si tratta di un estratto da un libro che ho pensato che avrebbe risolto tutto i miei problemi ma questo capitolo è in realtà solo un'introduzione alle possibilità di implementare il pattern MVP nei webform e conclude dicendo che non è davvero pratico. Il resto del libro riguarda test su asp.net MVC per quanto ho raccolto.

C'è anche questo nuovo progetto che mira a portare l'amore di nuovo alla piattaforma webforms:

0

In "normali" ASP.NET moduli web, la pagina/controllo utente è tecnicamente "responsabile" dell'elaborazione e impone il suo ciclo di vita sul codice. La pagina è il Presenter e la Vista, che ti piaccia o no.

La maggior parte dei tentativi di implementare il pattern MVP in questo ambiente aggiunge semplicemente eccessiva complessità a un ambiente già troppo complesso! Far finta che un'altra classe sia il presentatore è solo che ... fingendo. (Nei siti Web MVC, il controller controlla effettivamente il codice e la vista non lo fa, quindi questo argomento non si applica più.)

La mia raccomandazione è di lasciare che la vista gestisca il proprio ciclo di vita, e lascia che richiamare i repository e le classi del modello per recuperare/salvare dati e richiamare i comandi.

In questo approccio, le classi Modello non hanno bisogno di sapere nulla su System.Web. Queste stesse classi del Modello potrebbero quindi essere utilizzate in futuri siti Web MVC, o Silverlight, o come servizio Web per applicazioni WPF, o incorporate in un'applicazione WPF, ecc. Spetta alla Vista determinare come implementare (usando i Controlli) la risposta/i dati ottenuti dal modello.

Le classi del modello possono essere testate quanto desiderato se le si imposta correttamente per supportare l'iniezione di dipendenza.

Spero che questo aiuti!

2

Non so come un visitatore possa risolvere il problema. Ma perché non hanno i vostri contratti simile a questa:

public interface ISomeContract 
{ 
    void InstantiateIn(IControl container); 
} 

con un'implementazione IControl, possibilmente in un altro assembly per mantenere il vostro contratto di assemblaggio pulito, che avvolge l'ASP.NET System.Web.Control, come:

public class AspnetControl : IControl 
{ 
    public AspnetControl(System.Web.Control control) { } 

    // IControl members that dispatch to control 
} 

Anche se c'è un'alta probabilità che alla fine IControl finisca per sembrare molto simile a un System.Web.Control (e quindi a sconfiggere il punto di astrazione in primo luogo), sarebbe comunque molto verificabile, e la tua vista e i tuoi relatori non dovranno sapere nulla di ASP.NET.

+0

L'interfaccia IControl può esporre alcuni eventi del "ciclo di vita" che il controller può ascoltare - il più delle volte si finisce semplicemente per avvolgere gli eventi di moduli Web (forse una piccola classe di supporto potrebbe alleviare il dolore?) Ma, se si desidera visualizzare essere completamente stupidi, quindi devi conviverci. –