[Wymagania: .NET 3.5]
Załóżmy że mamy zrealizować bardzo proste zadanie: zmienić wszystkim osobom o jakimś wieku ich imię. Więc...
Mapujemy osobę:
  | 
 class Osoba {    public int Id { get; set; }    public string Imie { get; set; }    public int Wiek { get; set; }
     public override string ToString()    {        return string.Format("{0} {1} {2}", Id, Imie, Wiek);    } }
  Symulujemy działanie Data Access Layer (zwracającego wszystkie osoby)
  interface IDal {    IEnumerable<Osoba> Osoby { get; } }
  class Dal : IDal {    private IEnumerable<Osoba> osoby = new List<Osoba>()    {        new Osoba() { Id = 1, Imie = "osoba1", Wiek = 23},        new Osoba() { Id = 2, Imie = "osoba2", Wiek = 23},        new Osoba() { Id = 3, Imie = "osoba3", Wiek = 32}    };
     public IEnumerable<Osoba> Osoby { get { return osoby; } } }
  Tworzymy Data Access Object (LINQ wyciągający  osoby przy użyciu IDal) interface IDaoOsoby {    IEnumerable<Osoba> FindByWiek(int wiek); }
  class DaoOsoby : IDaoOsoby {    private IDal dal;
     public DaoOsoby(IDal dal)    {        this.dal = dal;    }
     public IEnumerable<Osoba> FindByWiek(int wiek)    {        return from osoba in dal.Osoby               where osoba.Wiek == wiek               select new Osoba() { Id = osoba.Id, Imie = osoba.Imie, Wiek = osoba.Wiek };    } }
 
  Serwis odpowiedzialny za zmianie imion (główna logika) interface IServiceOsoby {    void ZmienImie(int wiek); }
  class ServiceOsoby : IServiceOsoby {    private IDaoOsoby daoOsoby;
     public ServiceOsoby(IDaoOsoby daoOsoby)    {        this.daoOsoby = daoOsoby;    }
     public void ZmienImie(int wiek)    {        IEnumerable<Osoba> osoby = daoOsoby.FindByWiek(wiek);
         foreach (var osoba in osoby)        {            osoba.Imie = "zmienione imie";        }    } }
  Dzięki temu, że wszystko oparte zostało na interface'ach uzyskaliśmy bardzo elastyczną  i niepowiązaną żadnymi zależnościami strukturę. Świetnie, o to właśnie nam chodziło :)  Teraz wystarczy określić zachowanie przez "wstrzykniecie" konkretnych klas do konstruktorów.   Jeśli chodzi o testy jednostkowe, to stworzenie ich nie będzie żadnym problemem.  Dzięki użyciu Dependency Injection możemy testować jedną warstwę niezależnie od drugiej.  Tutaj przyjdą nam z pomocą Mock'i, lecz zostawmy sobie to na później :)
  Rzućmy okiem w jaki sposób możemy się tym wszystkim posługiwać.
 
  class Program {    static void Main(string[] args)    {                IDal dal = new Dal();        IDaoOsoby daoOsoby = new DaoOsoby(dal);        IServiceOsoby service = new ServiceOsoby(daoOsoby);
         service.ZmienImie(23);
                 ContainerBuilder cb = new ContainerBuilder();
         cb.Register<Dal>().As<IDal>().SingletonScoped();        cb.Register(v => new DaoOsoby(v.Resolve<IDal>())).As<IDaoOsoby>();        cb.Register(v => new ServiceOsoby(v.Resolve<IDaoOsoby>())).As<IServiceOsoby>();
         Container container = new Container();        cb.Build(container);
         container.Resolve<IServiceOsoby>().ZmienImie(23);    } }
 
 
  | 
  | 
Jest to tylko bardzo "drobny i ogólny" przedsmak tego co będzie działo w kolejnych postach :)
kod źródłowy
 
2 komentarze:
odnośnie wzorców projektowych to znalazłem zestaw fajnych przykladow i mysle ze warto opublikowac tego lina na Twoim blogu http://www.go4expert.com/forums/showthread.php?t=5127
no nie wygląda to za ciekawie:
cb.Register(v => new ServiceOsoby(v.Resolve())).As();
Prześlij komentarz