Modello Metodo Modello e Iniezione di dipendenza in una vista MVC

0

Ho lavorato per un cliente un certo numero di anni fa (chi non chiamerò per proteggere il colpevole) che periodicamente avrebbe informazioni come la seguente nella sua logica di visualizzazione:

if (client == "a") {
   // ...
}
else if (client == "b") {
   // ...
}
else {
   // ...
}

La loro piattaforma era ColdFusion (sì, non ridere) e questo faceva parte del modello per il loro processo di forma principale.

Ovviamente, questo è cringe-degno e terribile per numerose ragioni.

Recentemente stavo pensando a come avrei architettato quello. Il mio primo pensiero è stato quello di utilizzare un pattern Method Template combinato con Dependency Injection o Factory Pattern (per astrarre il ragionamento specifico del cliente) per la vista in questione.

Ovviamente, questa soluzione presuppone che tu costruisci viste sul "back-end". Questo però non è più il modo "standard" per farlo, e la maggior parte delle persone sembra essere passata a un qualche tipo di architettura MVC (ASP.NET MVC, Ruby on Rails, ecc.). Con questo in mente, ho notato che ASP.NET Core include supporto per Iniezione delle dipendenze nelle viste , così come MVC 4 .

Spero che questa non sia una domanda troppo semplice, ma è ciò che descrivo in precedenza un modo ancora valido per risolvere questo problema nei framework basati su MVC (in particolare ASP.NET MVC)? In particolare, sono confuso su come applicarlo a ASP.NET Views; So che le Views supportano Dependency Injection, ma esiste una sorta di analogia con un modello di metodo Template per le visualizzazioni ASP.NET che non determinerà un mix inappropriato della logica di business e di visualizzazione? O sono completamente sulla pista sbagliata?

    
posta EJoshuaS 10.02.2017 - 18:15
fonte

1 risposta

1

In ASP.Net, le Views sono ancora tipicamente renderizzate sul back-end, ma anche il tuo approccio suggerito - una Factory - è davvero un modo accettato per farlo.

Anche i metodi di template non ci vengono necessariamente dentro, puoi scegliere di usarli o meno; le implementazioni delle classi che contengono il codice specifico del client potrebbero utilizzarle come meccanismo per ottenere il polimorfismo tramite l'ereditarietà e l'implementazione di metodi o classi di base astratte, oppure si potrebbe optare per un'implementazione di interfaccia più semplice.

Ecco un esempio che utilizza uno scenario più classico di Controller- > Model- > View; si noti che non ho mostrato l'iniezione delle dipendenze e la factory è in realtà solo un'istruzione switch, quindi nella vita reale si utilizzerà una libreria IOC e si introduce la factory nel controller, oltre a utilizzare il built-in del contenitore abilità di fabbrica. Volevo solo chiarire le cose in questo caso.

public interface IClientSpecificFoo
{
    FooDataModel GetTheFoo();
}

Implementations of IClientSpecificFoo are not shown, this is where you might decide to implement them using inheritance or composition, it's really up to you.

public class ClientSpecificFooFactory
{
    public IClientSpecificFoo GetFooProviderFor(string clientId)
    {      
       switch(clientId)
       {
           case "clientA":
              return new ClientAFoo();
              break;
            case "clientB":
              return new ClientBFoo();
                break;
            default:
                return new GenericClientFoo();         
       }
    }
}

public class ClientSpecificController: Controller
{
    public ActionResult SomethingSpecific()
    {       
        var clientId=GetClientIdFromHeaders(); //or whatever way you identify the client
        var factory = new ClientSpecificFooFactory();
        var clientSpecificFoo = factory.GetFooProviderFor(clientId);
        var model = clientspecificFoo.GetTheFoo();
        return View(model);
    }
}

La vista stessa in tutti i casi sarebbe la stessa , rende solo il FooDataModel dato dal controller.

e questo è davvero.

    
risposta data 10.02.2017 - 20:35
fonte

Leggi altre domande sui tag