venerdì 9 settembre 2011

Leva lazy loading in. NET 4.0

Lazy loading è un modello di progettazione comune spesso utilizzati per la costruzione di molte risorse oggetti. E 'anche frequentemente utilizzata in combinazione con il singleton, e / o modelli di fabbrica. Lazy loading comporta la costruzione di un oggetto nel punto che serve, piuttosto che quando è dichiarata. Se mai l'oggetto finisce per essere utilizzato, non sarà mai completamente costruito.
Nelle versioni di Microsoft. NET Framework precedenti alla 4.0, si dovrebbe creare una propria logica lazy loading di approfittare di questo modello. Per fortuna. NET 4.0 include Pigro <T>, che è un implementazione generica del modello lazy loading. Primo sguardo diamo a come utilizzare Pigro <T> per implementare il modello Singleton. Il pattern Singleton crea una sola istanza di sempre per un oggetto, ed è spesso utilizzato per costruire gli oggetti che utilizzano risorse paura.
Creazione del Pigro Singleton
Per creare il nostro pigro classe caricata singleton, creiamo una statica di sola lettura Pigro <T> esempio della nostra classe. Facciamo anche il costruttore privato per evitare di essere chiamato in una classe derivata. Un'istanza della classe sarà sempre e solo essere creato se la proprietà istanza della classe si accede. Sfruttiamo Pigro <T> per assicurare questo comportamento. La classe Pigro <T> posticipa l'inizializzazione della sua classe fino a quando il. Valore della proprietà è accessibile. Questa particolare implementazione di inizializzazione pigra è conosciuta più comunemente come il modello di supporto valore. The Lazy proprietà Value <T> è un segnaposto che viene caricato solo nel punto che viene invocato.
VSMLazyLoading.Common namespace 

  { 

  public class Singleton 

  { 

  private static readonly Pigro <Singleton> m_instance = <Singleton> nuovo Pigro ();
        private Singleton () { }
        pubblico istanza static Singleton { ottenere { ritorno m_instance.Value; } } }
Alternate Pigro Singleton
La classe Pigro <T> permette anche di un comportamento simile out-of-the-box attraverso l'uso di un costruttore di overload. Per esempio, dire che abbiamo una classe ServiceProxy utilizzato per consumare un endpoint di servizio che abbiamo sempre e solo desidera inizializzare una volta in un modo thread-safe.
In primo luogo, noi creiamo la nostra classe proxy del servizio falso.
namespace VSMLazyLoading.Common 

  { 

  public class ServiceProxy 

  { 

  ServiceProxy pubblico () 

  { 

  Console.WriteLine ("proxy del servizio creato su {0}", DateTime.Now); 

  }
        pubblico stringa SayHello (string name) { String.Format ritorno ("Ciao, {0}", nome); } } }
Prossimo costruiamo il nostro pigro caricato classe proxy del servizio utilizzando la capacità della classe Pigro <T> per specificare una funzione di supporto valore e metodo di esecuzione. La bandiera LazyThreadSafetyMode.ExecutionAndPublication farà in modo che solo un thread può inizializzare l'oggetto e che una sola istanza è mai creato.
Delega <ServiceProxy> pigro = new Pigro <ServiceProxy> (() => nuova ServiceProxy (), 

  ServiceProxy caricate su {0} ", DateTime.Now)); 

  System.Threading.Thread.Sleep (1000); 

  string messaggio = proxy.Value.SayHello ("Eric"); 

  Console.WriteLine (String.Format ("Messaggio ricevuto : {0} ", messaggio)); 

  messaggio = proxy.Value.SayHello ("Giovanni"); 

  Console.WriteLine (String.Format ("Messaggio ricevuto: {0}", messaggio)); 

  Console.ReadLine ();

[Clicca sull'immagine per ingrandirla.]
Figura 1. Creazione della classe ServiceProxy.
Come si può vedere nella figura 1 , la classe ServiceProxy è stato costruito solo nel punto in cui il metodo SayHello è stato invocato.
Oggetto di carico semplici lazy
Spesso, potrebbe non essere necessario un singleton della classe, ma vorrei caricare pigramente un oggetto o un oggetto istanza figlio. Per prima cosa, diamo un'occhiata a come caricare pigri una intera classe semplice e poi vedremo come caricare pigro un oggetto più complesso che contiene un oggetto figlio. Prima di tutto creare una classe di test che conterrà le informazioni di una persona che vorremmo caricare pigramente.
VSMLazyLoading.Common namespace 

  { 

  public class Person 

  { 

  public int PersonID {get; set;} 

  public string Nome {get; set;} 

  public string Cognome {get; set;}
        Persona pubblico () { Console.WriteLine (String.Format ("persona, creata su {0}", DateTime.Now)); }
        pubblico override string ToString () { String.Format ritorno ("{0} {1}", Nome, Cognome); } } }
Poi abbiamo implementare un repository falso per caricare il nostro oggetto Person.
namespace VSMLazyLoading.Common 

  { 

  PersonRepository public class 

  { 

  carico Persona pubblico (int personId) 

  { 

  Pigro <Person> lazyPerson = <Person> nuovo Pigro (); 

  System.Threading.Thread.Sleep (1000); 

  lazyPerson.Value.FirstName = "Omero "; 

  lazyPerson.Value.LastName = "Simpson"; 

  lazyPerson.Value.PersonId = 1; 

  ritorno lazyPerson.Value; 

  } 

  } 

  }
Utilizziamo il comportamento predefinito di Lazy <T> per caricare pigramente un'istanza della classe Persona.
Console.WriteLine (String.Format ("Creato esempio pigro Persona inizializzato a {0}." DateTime.Now)); 

  PersonRepository personRep PersonRepository = new Date (); 

  persona Persona = personRep.Load (1); 

  Console.WriteLine (String . Format ("Persona: {0}", persona)); 

  Console.ReadLine ();

[Clicca sull'immagine per ingrandirla.]
Figura 2. La classe Persona.
Come si può vedere in figura 2 , un'istanza della classe Persona è creato solo nel punto in cui si accede la proprietà Value dell'istanza <Person> Pigro. La chiamata Thread.Sleep può essere rimosso, ed è stata aggiunta solo per sottolineare il punto che l'istanza oggetto persona viene rinviata fino a quando la proprietà Value è impostata.
Oggetto Caricamento complesso Pigro
Ora diamo un'occhiata a come rinviare solo il caricamento di un oggetto intero complesso. Il nostro oggetto complesso è record di un dipendente che contiene un record associato indirizzo. Vogliamo caricare pigramente sia per la persona e il suo record di indirizzo bambino.
Prima di tutto creare la nostra classe Indirizzo.

  namespace VSMLazyLoading 

  { 

  Indirizzo public class 

  { 

  public int AddressID {get; set;} 

  public int PersonID {get; set;} 

  AddressLine1 stringa pubblico {get; set;} 

  public string AddressLine2 {get; set;} 

  Città stringa pubblico {get; set ;} 

  Stato stringa pubblico {get; set;} 

  stringa CAP pubblico {get; set;} 

  Paese stringa pubblico {get; set;}
        Indirizzo pubblico () { Console.WriteLine (String.Format ("Indirizzo creato su {0}." DateTime.Now)); }
        pubblico override string ToString () { ritorno AddressLine1 Environment.NewLine + + + AddressLine2 Environment.NewLine + Città + "" + Stato + "," CAP + + + Environment.NewLine Paese; } }
Successivo creeremo la nostra classe Employee, che deriva dalla nostra classe Persona già creato.
namespace VSMLazyLoading.Common 

  { 

  pubblici dipendenti classe: Person 

  { 

  m_address privato <Indirizzo> pigro;
        pubblico LazyAddress <Indirizzo> Pigro { insieme { m_address = valore; } }
        MyAddress Indirizzo pubblico { ottenere { ritorno m_address.Value; } } }
Poi creiamo la nostra classe falso AddressRepository che caricare un record di indirizzo per una personId dato.
namespace VSMLazyLoading.Common 

  { 

  AddressRepository public class 

  { 

  pubblico Indirizzo LoadForPerson (int personId) 

  { 

  indirizzo Indirizzo = Indirizzo new () 

  { 

  AddressID = 1, 

  PersonID = personId, 

  AddressLine1 = "1234 Via Fake", 

  AddressLine2 = "Settore 7G", 

  Stato = "IL", 

  CAP = "60652", 

  Paese = "USA" 

  };
            l'indirizzo del mittente; } }
Ora creiamo la nostra classe falso EmployeeRepository, che pigramente carico un dipendente dai loro personId.Abbiamo anche pigramente carico record di indirizzo del dipendente.
namespace VSMLazyLoading.Common 

  { 

  EmployeeRepository public class 

  { 

  pubblici carico <Employee> Lazy (int personId) 

  { 

  AddressRepository addressRep AddressRepository = new Date (); 

  Pigro <Employee> lazyEmployee = 

  <Employee> nuovo Pigro (() => new Employee () 

  { 

  PersonID = personId, 

  Nome = "Eric", 

  Cognome = "Vogel", 

  LazyAddress = 

  nuovo Pigro <Indirizzo> (() => addressRep.LoadForPerson (personId)) 

  });
            ritorno lazyEmployee; } }
Infine utilizziamo il nostro EmployeeRepository per caricare pigramente il nostro record falsi dipendenti.
EmployeeRep EmployeeRepository EmployeeRepository = new Date (); 

  Pigro <Employee> lazyEmployee = employeeRep.Load (1); 

  System.Threading.Thread.Sleep (1000); 

  lavoratore dipendente = lazyEmployee.Value; 

  Console.WriteLine (String.Format ("Impiegato informazioni {0} {1} {2} ",) Environment.NewLine, employee.FirstName, employee.LastName); 

  System.Threading.Thread.Sleep (1000); 

  Indirizzo EmployeeAddress = employee.MyAddress; 

  Console.WriteLine (String.Format ("info Indirizzo: {0} {1}", Environment.NewLine, EmployeeAddress)); 

  Console.ReadLine ();

[Clicca sull'immagine per ingrandirla.]
Figura 3. pigramente caricare il record dei dipendenti.
Come si può vedere in figura 3 , il nostro record dei dipendenti è riuscita pigramente stato caricato così come il suo record di indirizzo associato.
Ricevi Pigro
Come si può vedere l'inizializzazione pigra e lazy loading sono due modelli di programmazione molto utile. Con l'introduzione della realizzazione pigro <T> nella quarta iterazione del. NET Framework, l'utilizzo di questi modelli di programmazione è diventata molto più accessibile. Come per tutti i modelli di programmazione, l'inizializzazione pigra e di carico dovrebbe essere usata con giudizio.

Nessun commento:

Posta un commento