Development z Zapomnianej Strony

..:: Paweł Hofman .NET Portal ::..

Czasem zdarza się sytuacja, w której ktoś, kto ma dostęp tylko do odczytu do naszego repozytorium SVN, chciałby w nim coś jednak zapisać. Udało mu się (lub jej) rozwiązać jakąś usterkę czy problem, albo usprawnić działanie. Moglibyśmy w tym miejscu dodać uprawnienia do zapisu i byłoby po sprawie.

Jednak czy na pewno? Zawsze jakieś “ale”! Z czegoś wynikał przecież fakt, że ów użytkownik nie posiadał pełni praw.

  • Czy wspomniana zmiana ma w ogóle sens i czy w ogóle istnieje? (może ktoś tylko chce wyłudzić dostęp)
  • Czy zmiany są w pełni przetestowane?
  • Czy nie wprowadzają luk w zabezpieczeniach i innych ukrytych furtek?
  • Czy zgadzają się one z konwencją nazewniczą i stosują projektowe formatowanie kodu?
  • Czy będziemy pamiętać, o cofnięciu uprawnień, gdy zmiany zostaną już wysłane do repozytorium?

Wyjściem z tej sytuacji może okazać się utworzenie "łatki" (patcha), która zawierała będzie tylko proponowane zmiany w konkretnych plikach i lokalizacjach. Później przekazanie jej zaufanej osobie w projekcie, która zmiany te może przejrzeć, ocenić i ma prawa do zapisu na serwerze. Oto jak się za to zabrać:

  1. Zapamiętanie zmian:

    svn diff > fix.diff

    (Rozszerzenie diff jest rozpoznawane przez wiele edytorów, podświetlając składnię podczas przeglądania, niemniej jednak każde inne byłoby równie dobre)

  2. Aplikacja zmian:

    patch -p0 -i fix.diff

    Teraz można sprawdzić, co i gdzie się zmieniło i po przeglądzie (oraz koniecznie testach) wysłać do repozytorium na serwerze.
  3. Wysłanie na serwer:

    svn commit –m “<message> 


Sam temat nie powinien być nieznany. Atrybuty to od takie dodatkowe adnotacje w kodzie, które możemy “przypiąć” do klas, metod, pól (itd.), które nadają im bardziej mistyczne własności, objawiające się już dalej podczas działania samej aplikacji. Ot, po prostu gdzieś później sami będziemy sprawdzać, czy dana klasa, pole czy metoda jest naznaczona wykonywać dla niej specjalny kod, który jest ukryty pod ‘if’ dla typowych elementów.

Jednakże te ‘systemowe’ atrybuty, które oferuje platforma czy kompilator .NET potrafią coś więcej. Dziś pokażę wybrane atrybuty .NET, które według mnie zasługują na szerszy rozgłos i użycie. Niejednokrotnie znajomość ich ułatwiła mi pracę, zatem mam nadzieję, że komuś jeszcze pomogą.

  • InternalsVisibleTo – sprawia, że bez ujawniania chronionych klas, “zaprzyjaźniony” tym atrybutem projekt testów jednostkowych (unit test) będzie widział wszystko i mógł tworzyć bez problemu instancje tych klas.
  • Conditional – pozwala wyrzucić z kodu te funkcje (ich definicje oraz wywołania), dla których wskazany warunek nie jest prawdziwy. Przydatne bardzo do logowania operacji w trybie ‘Debug’, które nie są nam potrzebne w trybie ‘Release’. Oczywiście funkcje muszą spełnić kilka warunków, ale to już odsyłam do dokumentacji.
  • AllowPartiallyTrustedCallers – pozwalamy używać swojego kodu nie w pełni autorytatywnemu kodowi (np. ściągniętemu z Internetu, który nie ma pełni praw wykonania na lokalnej maszynie).
  • TestClass / TestMethod – atrybuty używane w projektach testów od oznaczania pojedynczych testów. Głównie używane z Microsoft Testing Framework, jednakże z poziomu funkcjonalności API, posiada on komplementarne funkcje do NUnit, dzięki czemu przy użyciu kilku dyrektyw ‘using’ można te atrybuty przekształcić na identyczne z NUnit. Dzięki czemu nasz kod testuje się świetnie w systemie Window oraz na maszynach z Linuxem czy MacOS, gdzie dostępne jest Mono.


Z radością donoszę, że konkurs organizowany razem z Wrocławską Grupą .NET doszedł do skutku. Rozpoczyna się on już dziś (choć konkretniej to wczoraj) - 15 czerwca 2010! Trwał będzie aż do 21 września 2010!

W konkursie do wygrania cenne nagrody - 3 imienne komercyjne licencje na użytkowanie najnowszej wersji PostSharp 2.0, których fundatorem jest Paweł Hofman (CodeTitans.pl). Dalsze szczegóły dostępne są na stronie organizatorów tutaj. Życzę sukcesów i dobrej zabawy!

 

 PostSharp Wroc.NET



Nieprawdą jest, że na platformie .NET nie istnieją wskaźniki. W C# w sekcji unsafe, możemy spokojnie mieszać "typowy" kod .NET z operacjami na wskaźnikach. Tu jednak uwaga:

  1. sekcje unsafe muszą być propagowane w górę, a to oznacza, że i metoda, w której są zawarte, musi być również opisana jako niebezpieczna (czasem i cała klasa),
  2. oraz co dużo ważniejsze - podczas kompilacji modułu (assembly) wymagany jest przełącznik "/unsafe", zezwalający jawnie na używanie niebezpiecznych operacji na wskaźnikach.

Co ciekawe - dostępny staje się dobrze znany z C/C++ operator sizeof (a nie, jak wspomniano dotychczas tylko: Marshal.SizeOf() przy P/Invoke).

 

public unsafe void MakeTriple(int *pValue)
{
  *pValue=(*pValue)*3;
}

 

UWAGA!

Wskaźniki są niebezpieczne przede wszystkim z racji istnienia śmieciarza w .NET (zwanego przez niektórych również Garbage Collectorem, w skrócie GC). Otóż ów GC analizuje użycie wszystkich obiektów utworzonych w czasie życia programu .NET-owego i decyduje, które z nich mają być usunięte z pamięci. Nie wdając się zbytnio w szczegóły procesu decyzyjnego, należy zauważyć, iż obiekt, na który wskazywał wskaźnik, może bez żadnego powiadomienia oraz jawnej przyczyny zostać usuniętym, a jego miejsce zupełnie nieużywane. GC może, co gorsze, rozpocząć również proces upakowywania obiektów (usunąć fragmentację pamięci), aby zrobić więcej dla nowych obiektów, a tym samym wskażnik nie będzie już pokazywal poprawnej lokalizacji, bądź wskazywał inny obiekt.

Typowe referencje (do klas lub struktur) nadążają za tą polityką i nie są powodem tego typu błedów. Aby więc zabezpieczyć się, przed owymi niepożądanymi skutkami, używane jest przypinanie obiektów, które nie pozwala GC na żadne manipulacje wskazanym obiektem. Służy do tego słowo kluczowe fixed.

 

public unsafe static void Main()
{
  MyData data = new MyData();
 
fixed ( int *ptr = &data.valueField )
{
   *ptr = *ptr + 10;
}
}