skip to Main Content
Nhibernate Virtual Keyword Check

[NHibernate] Automatycznie sprawdź czy ‚properties’ są virtual

NHibernate wymaga od programisty, aby wszystkie Properties (właściwości) wewnątrz Enitity (encji / klasy POCO) były oznaczone słowem kluczowym virtual.

Dlaczego? bo…:

The quick answer to that question is: because we need members to be virtual in order to do our lazy loading magic/voodoo. — źródło StackOverflow

A teraz jak zrobić, aby automatycznie sprawdzać czy wszystkie properties spełniają wymagania? Wykorzystać Unit Testy!

Tutaj nie będę wyjaśniał jak skonfigurować środowisko, aby po każdej budowie uruchamiał się zestaw unit testów, bo to zależy od biblioteki którą wykorzystałeś.

W obecnym projekcie wykorzystuje xUnit.

A, kod wygląda tak:

[code lang=”csharp”] [Fact] public void CheckIfAllClassesInNamespaceHavePropertiesWithVirtualKeyword()
{
var assembly = Assembly.GetAssembly(typeof(User));
var @namespace = typeof(User).Namespace;
var typesInNamespace = GetTypesInNamespace(assembly, @namespace);

foreach (var type in typesInNamespace)
{
var properties = type.GetProperties();
foreach (var property in properties)
{
var userMessage = $"{type.FullName}.{property.Name}";
Assert.True(property.GetGetMethod().IsVirtual, userMessage);
}
}
}

private Type[] GetTypesInNamespace(Assembly assembly, string nameSpace)
{
return assembly.GetTypes().Where(t => String.Equals(t.Namespace, nameSpace, StringComparison.Ordinal)).ToArray();
}
[/code]

Zakładam, że wszystkie klasy POCO znajdują się w tym samym namespace (przestrzeni nazw). I to, że wszystkie klasy znajdujące się w tym namespace muszą spełniać te wymagania.

Jeżeli któraś property nie będzie posiadała oznaczenia virtual, wtedy test nie przejdzie pomyślnie i zostanie zaraportowana informacja o tym. Razem z przydatną ścieżką do property, do której zapomnieliśmy wstawić virtuala.

Paweł Sołtysiak

Programista, domowy kucharz i "amator amerykańskiej polityki".
Zbieram informacje z całej sieci, po odrzuceniu chwastów i dodaniu swojej opinii publikuje na blogu.

  • Spoko wpis, podobny patent robił Procent na dotnetConfPL. Ja jednak nie zakładałbym, że POCO będą zawsze w tym samym namespace i że tylko one się tam znajdą. Oznaczyłbym je jakimś interfejsem i dodał warunek przy wyciąganiu typów z assembly, że muszą dany interfejs implementować. Wtedy masz 100%, że wyciągasz to co potrzeba.

    • Paweł Sołtysiak

      Dobry pomysł.

      „Wtedy masz 100%, że wyciągasz to co potrzeba.”
      Chyba, że zaimplementujesz interfejs tam gdzie nie powinieneś 🙂 Najsłabszym punktem rozwiązań według jakieś konwencji jest człowiek, której tej konwencji nie stosuje 🙂

      • Bardziej niż interfejs pasuje tutaj atrybut. Sorry za poślizg w czytaniu.

Back To Top