2011-10-20 7 views
5

klasy bazowe dla strony i UserControl:Jak utworzyć klasę podstawową dla Kontrolki strony i użytkownika?

public class MyWebPage : System.Web.UI.Page { } 

public class MyUserControl : System.Web.UI.UserControl { } 

Helper, że któryś z nich może używać:

void SetSessionValue<T>(string key, T value) { Session[key] = value; } 

Jak mogę osiągnąć coś jak poniżej?

public class WebObject // can't inherit from both Page and UserControl { 
    protected void SetSessionValue<T>(string key, T value) { 
     Session[key] = value; 
    } 
} 

public class MyWebPage : WebObject { } 

public class MyUserControl : WebObject { } 

Aktualizacja: Podekscytowałem się po raz drugi, mając nadzieję, że uda mi się go rozwiązać w ten sposób, ale niestety nie kompiluje.

public class WebObject<T> : T 
{ 
} 
public class MyWebPage : WebObject<System.Web.UI.Page> 
{ 
} 
+1

Ile takich metod będzie można i ile kodu będzie w każdej metodzie? Dlaczego po prostu nie powielać kodu?Ta jedna linijka wydaje się być krótka, aby się tym martwić. Ponadto, jeśli 'Strona' i' UserControl' mają jakąś wspólną klasę podstawową, możesz po prostu utworzyć metodę rozszerzenia tego typu. Na przykład. na 'System.Web.UI.Control' lub' System.Web.UI.TemplateControl' - możesz to zrobić tylko, jeśli nie potrzebujesz stanu ze swojej niestandardowej klasy bazowej. –

Odpowiedz

4

Nie możesz. I tak nie jest łatwo. Polecam po prostu tworzenie klasy bazowej dla stron i kontroli użytkowników oraz powielanie wspólnego kodu w obu. Ponieważ kontrole użytkownika są zawarte na stronach, można również delegować metod w klasie kontrolnej użytkownika podstawa do klasy widoku bazowa po prostu oddając właściwość Page na swój typ:

// Code in the MyUserControlBase class 
public int SomeCommonMethod() { 
    return ((MyBasePageType)this.Page).SomeCommonMethod(); 
} 

Można też uczynić swoje życie nieszczęśliwy przez tworzenie interfejsu implementowanego przez obie klasy bazowe i użycie metody DI do przechwytywania metod i wywołań właściwości, które następnie byłyby kierowane do pewnej typowej klasy zastępczej, która faktycznie zapewnia implementację. Prawdopodobnie bym tam nie poszedł :)

+0

W końcu utworzyłem klasę Kontekstową, która jest tworzona przez stronę bazową, i umieszczam uzyskujący właściwość w bazie kontrolnej za pomocą wzorca opisanego w tym fragmencie tutaj - dzięki. –

1

IIRC obie strony i UserControl dziedziczą TemplateControl więc może być w stanie odziedziczyć od tego.

+0

Tak, patrzyłem na to. Zauważ, że właściwość Session nie znajduje się w klasie TemplateControl. Gdyby tak było, po prostu musiałby dodać metodę rozszerzenia do TemplateControl. – AaronLS

1

Jednym ze sposobów uniknięcia powielania jest posiadanie klasy pomocniczej, utworzonej za pomocą właściwości statycznej i dostępnej z dowolnego miejsca w interfejsie użytkownika (Page, UserControl lub dowolne inne klasy w warstwie UI) .

Coś jak:

public class ApplicationContext 
{ 
    // Private constructor to prevent instantiation except through Current property. 
    private ApplicationContext() {} 

    public static ApplicationContext Current 
    { 
     get 
     { 
      ApplicationContext current = 
       HttpContext.Current.Items["AppContext"] as ApplicationContext; 
      if (current = null) 
      { 
       current = new ApplicationContext(); 
       HttpContext.Current.Items["AppContext"] = current; 
      } 
      return current; 
     } 
    } 

    public void SetSessionValue<T>(string key, T value) 
    { 
     HttpContext.Current.Session[key] = value; 
    } 
    ... etc ... 
} 

Pojedyncza ApplicationContext instancja będzie żył przez cały okres bieżącego żądania, i można użyć ApplicationContext.Current.SetSessionValue i innych wspólnych elementów z dowolnego miejsca w warstwie UI kodu.

Często robię coś więcej niż umieszczanie metod ogólnych, takich jak Twoja SetSessionValue, w takich klasach pomocniczych i mogą tam być dostępne specyficzne właściwości aplikacji, np.

public class ApplicationContext 
{ 
    ... as above ... 

    public ShoppingBasket ShoppingBasket 
    { 
     ShoppingBasket shoppingBasket = 
      HttpContext.Current.Session["Basket"] as ShoppingBasket; 
     if (shoppingBasket == null) 
     { 
      shoppingBasket = ... e.g. retrieve from database 
      HttpContext.Current.Session["Basket"] = shoppingBasket; 
     } 
     return shoppingBasket; 
    } 
} 

W ten sposób można uzyskać dostęp do aktualnego ShoppingBasket wystąpienie dowolnego miejsca w interfejsie, nie znając ani dbając, że to buforowane w sesji - to szczegółów wdrażania znany tylko swojej klasie ApplicationContext.

0
  • 1) Dokonaj statyczną klasę, która ma wszystkie zmienne, funkcje trzeba
  • 2) Zrób swój własny UserControl i stronę klasę i uczynić te zajęcia nazywają swoje funkcje statyczne w Pre_Init i obciążenia nadpisuje
  • 3) Spraw, aby każda strona dziedziczyła twoje klasy bazowe.

To najprostszy sposób.

+0

Nie jest to dobry pomysł. Klasy statyczne są wrogiem zastrzyku zależności i nie pozwalają ci robić makiet dla łatwego testowania. Są to także single, które mogą nie działać dobrze. Jeśli potrzebujesz klasy pomocniczej, której używają obie klasy; utwórz normalną klasę, która jest implementacją interfejsu i wstrzyknij interfejs w miejsca, których potrzebujesz do budowy tych obiektów. W ten sposób możesz wyśmiewać to, co chcesz, dla łatwego testowania i nie skończy się na statykach zaśmiecających twój kod i utrudniających testowanie. –

Powiązane problemy