Rifacimento di pagine Web con controlli utente

2

È buona norma utilizzare molti controlli utente per aiutare a ridefinire un'applicazione Web?

Nel mio caso, è un sito Web ASP.NET di Webforms VB.NET. Tutte le nostre pagine sono organizzate in sezioni che, pur essendo correlate e appartengono alla stessa pagina, non hanno bisogno di interagire tra loro. Ogni sezione contiene molti controlli asp (caselle di testo, etichette, viste griglia, pulsanti, ecc.). La maggior parte sono moduli che l'utente compilerà per inviare o visualizzare i dati. A causa delle sezioni multiple e del numero multiplo di controlli per sezione, i file di codice possono diventare molto grandi.

Trasformare ciascuna sezione in un controllo utente sembra un buon modo per ridefinire le pagine. Ogni sezione ora viene organizzata in un proprio file e il codice viene estratto dal file di grandi dimensioni.

Probabilmente ci ritroveremo con oltre 100 controlli utente che probabilmente non verranno riutilizzati su altre pagine, tuttavia sembra un'opzione migliore rispetto a Classi parziali in quanto ci consente di utilizzare Caricamento lento con i controlli utente per migliorare i tempi di caricamento della pagina.

Nota: un sacco di refactoring sta per accadere se usiamo i controlli utente o no. Se scegliamo di suddividere la nostra pagina utilizzando i controlli utente, il codice che ogni controllo conterrà verrà anche rifattorizzato, suddividendolo in classi e funzioni laddove possibile. Abbiamo l'idea che i controlli utente possano essere un modo per migliorare il nostro codice in aggiunta agli altri refactoring come descritto nella domanda.

    
posta Jeremy K 14.10.2014 - 12:59
fonte

3 risposte

1

Ho trovato che c'è modo più ripetizioni di codice in un'applicazione WebForms che è immediatamente evidente. Ho battuto la testa con questo problema esatto, e ho trovato diversi rimedi.

ASCIUGGI I tuoi UserControls (e anche i modelli!)

Quando guardi ogni singola pagina, vedi tante differenze che non puoi immaginare che il codice venga ripetuto. Guarda i dati che stai salvando nel database. Su un'applicazione su cui lavoro, abbiamo circa 10 diverse forme che salvano tutti i record "persone" nel database con gli stessi campi, ma in ogni vista sono disponibili diversi campi. All'inizio pensavo che ci fosse troppo codice personalizzato, ma poi ho capito che sono tutti gli stessi dati nella stessa tabella. Ho creato un controllo utente generico per modificare oggetti "persone" - Compila i campi modulo in base a un modello di dominio e ripopola il modello di dominio in base ai campi modulo.

Ho anche creato un modello di visualizzazione che comprendeva la logica di visualizzazione e quindi l'utilizzo per influire sul controllo utente.

Modello di dominio persona

public enum PersonType
{
    Applicant = 1,
    Foo = 2
}

public class Person
{
    public int Id { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string TaxId { get; set; }
    public IEnumerable<PersonType> Types { get; private set; }

    public bool IsApplicant
    {
        get { return Types.Contains(PersonType.Applicant); }
    }

    public bool IsSomethingElse
    {
        get { return Types.Contains(PersonType.Foo); }
    }

    public bool RequiresTaxId
    {
        get { return IsApplicant; }
    }
}

Modello vista persona

public class PersonViewModel
{
    public Person Person { get; private set; }

    public bool ShowTaxIdField { get { return Person.RequiresTaxId; } }

    public PersonViewModel(Person person)
    {
        Person = person;
    }
}

(A Snippet Of) Il controllo utente

<p id="TaxIdField" runat="server">
    <asp:Label ID="TaxIdLabel" runat="server" AssociatedControlID="TaxId">Tax Id:</asp:Label>
    <asp:TextBox ID="TaxId" runat="server" />
</p>

Il codice C # dietro

public partial class PersonUserControl : System.Web.UI.UserControl
{
    public void SetModel(PersonViewModel model)
    {
        TaxId.Text = model.Person.TaxId;
        TaxIdField.Visible = model.ShowTaxIdField;
        // ...
    }

    public PersonViewModel GetModel()
    {
        var model = new PersonViewModel(new Person()
        {
            TaxId = TaxId.Text.Trim(),
            // ...
        });

        return model;
    }
}

Push Business Logic nei modelli di dominio

Rimuovere il codice duplicato significa anche spostare la logica di business nei tuoi modelli di dominio. Questa "persona" richiede un codice fiscale? Bene, la classe Person dovrebbe avere una proprietà o un metodo chiamato IsTaxIdRequired . Guarda Creare modelli di domini malvagi per alcune idee aggiuntive.

Ma utilizzo i DataSet ...

Stop! Subito. Stai intimamente legando il tuo codice C # allo schema del database sottostante. Anche se devi scrivere a mano un livello di mappatura tra gli oggetti DataSet e i tuoi modelli di dominio, sarai ancora più avanti perché ora puoi raggruppare le regole di comportamento e aziendali con i tuoi dati in una classe pulita e ordinata. Usando DataSet, i tuoi file Design e Code-Behind implementano la logica di business! Ferma questo il prima possibile. Anche se il framework WebForms non aderisce strettamente al modello Model-View-Controller, il codice C # dovrebbe essere visto come "Controller" e il file Design dovrebbe essere visto come "View". L'unica cosa rimasta è il "Modello", che non dovrebbe essere un DataSet . Gli oggetti DataSet forniscono dati, ma nessun comportamento porta a una logica aziendale ripetuta.

Utilizza classi di supporto per inizializzare l'interfaccia utente

Tutto ciò che vedo spesso in 15 diversi UserControls:

public InitStateDropdownList()
{
    ddlState.DataSource = ...
    ddlState.DataBind();
    ddlState.Items.Insert(0, new ListItem("Select", string.Empty));
}

Spingilo in una classe helper:

public static class DropDownListHelper
{
    public static void InitStates(DrowDownList list)
    {
        list.DataSource = // get options from database or session
        list.Items.Insert(0, new ListItem("Select", string.Empty));
        list.DataBind();
    }
}

E usalo:

DropDownListHelper.InitStates(ddlState);

Alcune persone si arrabbiano con le classi di "helper", ma è sicuramente meglio che scrivere quelle che sono essenzialmente le stesse 3 linee di codice in più punti. Anche se non puoi creare controlli utente super generici, elimina almeno il codice ripetitivo che inizializza i componenti al caricamento della pagina.

Quando BIG riscrive la risposta?

Quasi mai. Per tutte le mie lamentele riguardo al framework WebForms, questo in least compartimenta pagine e moduli, che è un'ottima impostazione per un lavoro di refactoring a lungo termine. La chiave è aggiungere copertura di prova . Ho avuto molto successo usando i Test CodedUI e SpecFlow per testare le applicazioni WebForms, dal momento che la maggior parte se non tutta la logica di business è sparsa tra C # e ASP in 19 file diversi. Almeno scrivi alcuni test per convalidare le regole di business esistenti non si rompano durante le molte sessioni di refactoring che hai nel tuo futuro.

    
risposta data 21.10.2014 - 19:37
fonte
0

Nel mondo reale se non hai intenzione di riutilizzare codice / controlli, non perdere tempo a renderli riutilizzabili. Non ne vale la pena. Tuttavia, se puoi riutilizzarli in futuro, rendili riutilizzabili.

Dici "Sito Web ASP.NET Winforms VB.NET", tuttavia non puoi averlo come Winforms e ASP.Net/Website dovrebbe essere uno o l'altro.

    
risposta data 21.10.2014 - 12:27
fonte
0

Non creare mai un controllo utente che verrà utilizzato una sola volta, tutto ciò che farà è nascondere i problemi reali e rendere le cose ancora più difficili. Se si dispone di enormi file di codice dal numero di controlli su una pagina, è necessario creare più pagine separate e non controlli utente. Sembra già che tu abbia più sezioni su una pagina che potrebbero essere relativamente facilmente pagine completamente separate.

    
risposta data 21.10.2014 - 20:06
fonte

Leggi altre domande sui tag