Month: September 2014
Dowiedziane przy okazji DevDay
Pola i konstruktor lądują na dole klasy bo nas nie interesują.
[RoutePrefix("api/declarations")] public class DeclarationsController : ApiController { [Route("{declarationId:int}")] public IHttpActionResult GetDeclaration(int declarationId) { Declaration declaration = declarationsRepository.Get(declarationId); if (declaration == null) { return NotFound(); } return Ok(declaration); } // methods // fields and contructor readonly DeclarationsRepository declarationsRepository; public DeclarationsController(DeclarationsRepository declarationsRepository) { this.declarationsRepository = declarationsRepository; } }
Domyślnie nie tworzyć klas public. Pomoże to w enkapsulacji. Ma to zastosowanie gdy mamy architekturę wielowarstwową (która mieści się w wielu projektach). Jeśli mamy tylko jeden projekt to też piszmy bez public i tak wszystko będzie widoczne. Klasy domyślnie dostają internal, który oznacza że są widoczne w obrębie projektu.
Jeśli chodzi o testy to można nadać
[assembly: InternalsVisibleTo("App.Tests")]
FireShot – zrób screenshot całej stronie
W firefoxie można zainstalować dodatek:
https://addons.mozilla.org/pl/firefox/addon/fireshot/
- trzeba go zainstalować i pojawi się w prawym górnym rogu (literka ‘S’)
- będąc na stronie z ofertą można kliknąć ten przycisk i poczekać aż program zrobi zdjecia całej stronie,
- potem można edytować, na górze jest przycisk “Text”,
- dalej klikamy gdzieś w obrazek i możemy dodawać własne opisy,
- po prawej stronie jest można też zmieniać kolory i rozmiar napisów.
Visual Basic .NET – częste problemy
Przekazywanie argumentów ByRef
W Visual Basic .NET w sygnaturze funkcji explicite podajemy czy argument jest przekazywany ByVal (przez wartość) czy ByRef (przez referencję). W C# domyślnie jest to przez wartość np
void Foo(int number)
W C# trzeba dodać specjalny modifykator ref, żeby po wyjściu z funkcji mieć inną wartość (14).
void Foo(ref int number) { number = 14; } void Bar() { int sum = 5; Foo(sum); Console.WriteLine(sum); // 14 }
Ten kod wygląda na nienormalny i czegoś takiego nie powinniśmy nigdy pisać. Jeśli chcemy dostać coś z funkcji to robimy to poprzez zwracane argumenty a nie modyfikowanie istniejących.
W Visual Basic takie sytuacje zdarzają się dosyć często więc dużo trudniej przewidzieć co się dzieje w kodzie, gdy ma się pewne nawyki z C#.
Proponuję więc aby wszystkie parametry były przekazywane ByVal W istniejącym kodzie dla czytelności i zrozumienia newralgicznych kawałków które refaktorujemy, proponuję zamieniać ByRef na ByVal. Czasem może to wymagać w kodzie np:
Private Sub Foo(..., ByRef number As Integer) ' .... number = 14 End Sub
na
Private Function Foo(...) As Integer ' .... Return 14 End Function
czyli całkiem prostych. Czasem będzie to jednak trudniejsze …
“And” to nie to samo co “AndAlso”
W C# zdarza się pisać następujący warunek. Operator && nie wykona drugiego sprawdzania jeśli pierwsze zwróci ‘false’.
if(student != null && student.Age >= 18){}
W VB już nie jest to takie oczywiste. Mamy dwa operatory: And oraz AndAlso i tylko ten drugi jest odpowiednikiem C#’owego &&.
If student IsNot Nothing And student.Age >= 18 Then ' Pewny strzał w NullReferenceException prędzej czy później. End If If student IsNot Nothing AndAlso student.Age >= 18 Then ' prawidłowo End If
Operator “And” wykona również drugi warunek mimo że pierwszy zwróci false. Jest to bardzo nieintuicyjne jak na to w jaki sposób pisze w .NET programy.
Moja rada to przerobić cały kod, aby korzystał z AndAlso.
Instalacja SQL Management Studio 2012
Po pobraniu i uruchomieniu trzeba wybrać aktualną instancję SQL Server (Express) i dopiero wtedy gdzieś w opcjach dodatkowych doinstalować Management Studio.
Powolna migracja AngularJS z 1.2 do 1.3
https://github.com/angular/angular.js/blob/master/CHANGELOG.md#since-1217-and-130-beta10
Dodaj <base href="/"> do <head>
Nancy – zasłanianie się danych podczas bindowania z POST
Mamy następujący kawałek kodu. Nancy – moduł REST który coś tam robi.
public class TopicsModule : NancyModule { public class Note { public int Id { get; set; } public string Content { get; set; } } public TopicsModule() : base("/api/topics") { Post["/{id:int}"] = parameters => { var id = (int)parameters.id.Value; Note note = this.Bind<Note>(); // note.Id == ? // ... } } }
Wywołujemy request typu POST pod adres http://localhost/api/topics/11
z następującym body:
{ id: 44, content: 'nowy tekst' }
Teraz pytanie – Jaka będzie wartość note.Id?
Spodziewałem się wartości 44 i trochę się namęczyłem szukając dlaczego nie jest to 44.
Mechanizm bindowania działa tak, że najpierw brane są wartości z URLa, później z Query stringa, a dopiero na końcu z body requestu. W powyższym przypadku note.Id wynosić więc będzie 11.
Musimy więc w kodzie zapewnić aby nie było kolizji tych nazw, np:
public class TopicsModule : NancyModule { public class Note { public int Id { get; set; } public string Content { get; set; } } public TopicsModule() : base("/api/topics") { Post["/{topicId:int}"] = parameters => { var topicId = (int)parameters.topicId.Value; Note note = this.Bind<Note>(); // note.Id == 44 // ... } } }