Dynamiczne tworzenie klas

0

Witam,

Aktualnie jestem w trakcie pisania pewnej biblioteki i chcę tam zaimplementować LazyLoading / wzorca Proxy.

Ogólnie zastanawiam się, czy możliwe jest dynamiczne tworzenie klas, bądź możliwe, że jest lepszy sposób na rozwiązanie tego problemu. Aby objaśnić co chcę mniej-więcej osiągnąć przedstawię trochę kodu. Sposób musi być uniwersalny.

Użytkownik ma jakąś klasę i metodę, która udostępnia jego klasę.

  public class Czlowiek
  {
    public virtual string Imie { get; set; }
    public virtual string Nazwisko { get; set; }
    public virtual int Wiek { get; set; }
  }

  public Czlowiek PobierzCzlowiek();

W tym momencie chcę aby metoda PobierzCzlowiek nie zwracała klasy Człowiek jako takiej, tylko klasę dziedziczącą po Człowiek (implementującą proxy)

 
public class CzlowiekReturn : Czlowiek
  {
    public void Execute()
    {
      base.Imie = "Jan";
      base.Nazwisko = "Kowalski";
      base.Wiek = 20;
    }

    public override string Imie
    {
      get
      {
        if (base.Imie == null)
          Execute();

        return base.Imie;
      }
      set
      {
        base.Imie = value;
      }
    }

    public override string Nazwisko
    {
      get
      {
        if (base.Nazwisko == null)
          Execute();

        return base.Nazwisko;
      }
      set
      {
        base.Nazwisko = value;
      }
    }

    public override int Wiek
    {
      get
      {
        if (base.Wiek == null)
          Execute();

        return base.Wiek;
      }
      set
      {
        base.Wiek = value;
      }
    }
  }

Oczywiście metody Execute być nie musi, mogę obiekt bazowy wypełnij inaczej. Zastanawiam się, czy tworzenie takich klas "nazwaReturn" może odbywać się dynamicznie za pomocą refleksji ?

0

Po pierwsze: koniecznie zmień nawyki nazewnictwa. Mieszasz polsko-angielskie nazwy, to istna tragedia. Klasa zlowiekReturn, właściwość Imie, a metoda Execute().
Po drugie: musisz podać kontekst zastosowania. Zawsze przy wzorcach trzeba takowy napisać.

Użyj adaptera zamiast proxy. Niech ów 'CzłowiekReturn' dziedziczy po człowiek i jednoczesnie niech ma do obiektu takiej klasy asocjację. Wtedy przesłaniając właściwości "przekierowujesz" je do właściwości obiektu agregowanego.

0

@siema cześc i czołem

  1. Nazwy były dla przykładu.
  2. Twoja wypowiedź nic nie wnosi do rozwiązania problemu.

Nie wiem czemu, moderator przeniósł to do działu newbie... widocznie problem jest trywialny...

Poczytałem troszkę na własną rękę i okazało się, że C# ma wbudowaną klasę taką jak TypeBulider, a mój problem można rozwiązać tylko przez wczepianie kodu IL.
Tutaj jest ciekawy artykuł na ten temat http://codeguru.pl/Articles/14109/Comments.aspx.
Później w miarę możliwości dowiem się, czy MS wprowadził jakieś udogodnienia, gdyż artykuł jest z 2004 roku, wiele się mogło zmienić :)

Tamat nie uważam za zamknięty, gdyż może ktoś mnie naprowadzi na łatwiejszy sposób wprowadzenia lazy loading.

0

Może i jest łatwiejszy sposób, tylko Twój opis problemu jest niejasny (przynajmniej dla mnie).
Czy metoda PobierzCzlowiek nie może po prostu zwracać jakiegoś interfejsu implementowanego przez wszystkie klasy?

0

Ok jeśli opis nie jasny to sorki, postaram się opisać wszystko bardziej szczegółowo.

Piszę na zaliczenie prostego ORM i biblioteka jako taka już działa. Chciałem jako dodatek wprowadzić Lazy Loading. Postaram się w uproszczeniu to przedstawić.

Użytkownik najpierw tworzy klasę DB, która dziedziczy po IMapper, oraz ustawia klasy, które będą mapowane.

 
public class Person
{
  public virtual string Name {get;set;}
  public virtual int Age {get; set;}
}

public class DataBase : IMapper
{
  MapperSet<Person> Persons = new MapperSet<Person>();
}

W tym momencie mamy już zbudowane klasy, wyciąganie z bazy danych wygląda bardzo podobnie (czasami identycznie) jak w EF

 
Person p = Persons.Single(x=>x.Name == "Jan");

W tym momencie (zwracany rezultat przez Persons => czyli klasa Person), będę sprawdzał czy properties w klasie są virtualne, jeśli są to używam Lazy Loading.

Pomyślałem, żeby Lazy Loading zaimplementować tak, że zamiast klasy Person, zwracać klasę dziedziczącą po person np. PersonReturn, która przysłania wszystkie properties w taki sposób :

 
public class PersonReturn : Person
{
  //tutaj muszę wstawić jakąś metodę, która faktycznie wyciągnie dane z bazy, w uproszczeniu ma to tak wyglądać
  private string Query = "SELECT TOP(1) FROM Person WHERE Name = 'Jan'";
  private Execute()
  {
    p = (Person)Db.TableToObject(Query);
  }
  Person p;

  public override string Name 
  {get
   {
     if(p == null)
      p = Execute();
    
    return p.Name;
   }
   set {}
   }

  //tutaj tak samo
  public override int Age {get; set;}
}

1 użytkowników online, w tym zalogowanych: 0, gości: 1