C #. Modello per la creazione dinamica di report

-3

Questo è un esempio semplificato, il problema attuale ha più report e punti dati richiesti. Inoltre, più rapporti potrebbero essere aggiunti in futuro, quindi mi piacerebbe avere qualcosa di "intelligente" e dinamico.

Diciamo che ho i seguenti metodi:

public CustomerInfo GetCustomerInfo(int customerId){/* implementation */ }
public AccountInfo GetAccountInfo(int customerId){/* implementation */ }
public BankInfo GetBankInfo(int bankId){/* implementation */ }

Ho tre rapporti:

Report1 -> Needs CustomerInfo, AccountInfo
Report2 -> Needs CustomerInfo, AccountInfo
Report3 -> Needs AccountInfo, BankInfo

Senza fare se / else o qualsiasi altra logica sequenziale, come posso determinare quali metodi devono essere chiamati per un determinato elenco di report che avrà rapporti da 1 a N richiesti?

In questo momento ho qualcosa di simile a questo:

// I receive a list of reports to print for a particular client
var reports = new List<string> { "Report1", "Report2" }; // we get this as a param in a method
var int clientId = 12345; // we get this as a param in a method

//method implementation
foreach(var report in reports)
{
    var model = new ReportModel
    {
        CustomerInfo = GetCustomerInfo(clientId),
        AccountInfo = GetAccountInfo(clientId),
        BankInfo = GetBankInfo(bankId)
    }

    PrintReport(model);
}

Il problema con questo approccio è che gli stessi tre metodi vengono chiamati 3 volte anche se

  1. non abbiamo bisogno di chiamarli tutti (BankInfo non è necessario per Report1 e Report2) in modo che la chiamata venga sprecata.
  2. chiamiamo GetCustomerInfo e GetAccountInfo vengono chiamati due volte quando dovrebbe essere stato chiamato una volta, sono gli stessi dati condivisi per entrambi rapporti.

Come posso migliorare questo per essere più intelligente su quali metodi devono essere chiamati. C'è un modello che potrei usare?

    
posta ornstai 05.03.2018 - 15:03
fonte

2 risposte

1

Sospetto che mi manchi qualcosa nella tua domanda, poiché la soluzione sembra piuttosto ovvia: crea model , una volta, prima di eseguire il looping dei rapporti.

//method implementation
var model = new ReportModel
{
    CustomerInfo = GetCustomerInfo(clientId),
    AccountInfo = GetAccountInfo(clientId),
    BankInfo = GetBankInfo(bankId)
}

foreach(var report in reports)
{

    PrintReport(model);
}
    
risposta data 05.03.2018 - 17:25
fonte
0

Pensa che quello che stai cercando è Pigro .

var model = new ReportModel
{
    CustomerInfo = new Lazy<CustomerInfo>( () => GetCustomerInfo() ),
    AccountInfo = new Lazy<AccountInfo>( () => GetAccountInfo(clientId) ),
    BankInfo = new Lazy<BankInfo>( () => GetBankInfo(bankId) )
};
Console.WriteLine(model.BankInfo.Value.AccountNumber); //Call isn't made until this line executes

Ora tutti e tre i dati sono disponibili dal modello, ma se il chiamante non ne usa alcuni, in realtà non verranno popolati e non causeranno alcun sovraccarico. Bene, un pochino. Quasi nessuno.

Fai attenzione alle chiusure se stai passando degli argomenti (ad esempio clientId ) . Non saranno valutati fino a quando la chiamata non viene eseguita.

    
risposta data 06.03.2018 - 10:09
fonte

Leggi altre domande sui tag