Jakiś czas temu miałem przyjemność pracy przy aplikacji webowej (ASP.NET MVC) wykorzystującej do uwierzytelniania framework ASP.NET Identity. Założenia projektu były następujące:
- Korzystamy z istniejącej bazy użytkowników (SQL Server), utworzonej wcześniej na potrzeby innego projektu (w związku z tym, schemat bazy danych jest raczej „nieruszalny”). Kluczem głównym dla tabel, z których korzystamy (Użytkownicy, Role, itp.) jest typu „int”.
- Jako mechanizm dostępu do danych wykorzystujemy najnowszą wersję Entity Framework (podejście „DB First”, generujemy model encji (EDMX) na podstawie istniejącej bazy danych i jedziemy z pisaniem kodu).
Wszystko to brzmi bardzo fajnie („tu frejmwork, tam frejmwork…”), niestety okazało się, że ASP.NET Identity niekoniecznie chce współpracować w prosty sposób z repozytorium, które nie jest w 100% zgodne z przyjętymi przez jego twórców założeniami (np. tym, że klucz główny w tabeli jest zawsze typu „string”… seriously Microsoft?).
Dodatkowo, całość wymusza na nas podejście, które niekoniecznie jest zgodne ze znanymi mi praktykami dobrego programowania. Przykładowo – domyślne metody klas ApplicationSigninManager i ApplicationUserManager wymagają do prawidłowego działania “wstrzyknięcia” obiektu implementującego następujące interfejsy:
public class UserRepository<TUser> :
IUserStore<TUser, int>,
IUserLoginStore<TUser, int>,
IUserClaimStore<TUser, int>,
IUserRoleStore<TUser, int>,
IUserPasswordStore<TUser, int>,
IUserSecurityStampStore<TUser, int>,
IUserLockoutStore<TUser, int>,
IUserTwoFactorStore<TUser, int>,
IUserPhoneNumberStore<TUser, int>
where TUser : User
{…}
Ilość wymaganych interfejsów kłóci mi się trochę z zasadą „pojedynczej odpowiedzialności” (ang.: „single responsibility”). Oczywiście możemy wszystko poprzerabiać, poprzeciążać, itd., itp. W takim przypadku pojawia się jednak pytanie, czy nie prościej będzie zbudować projekt od podstaw, zamiast korzystać z dostarczanych szablonów i bibliotek.
Na szczęście, ponieważ w programowaniu nie ma rzeczy niemożliwych, możemy zmusić całość do działania. Trzeba w tym celu nieco pokombinować. Poniżej znajdziecie odnośnik do źródeł przerobionej przeze mnie domyślnej aplikacji ASP.NET MVC w taki sposób, żeby korzystała ona z modelu encji wygenerowanego za pomocą podejścia „DB First”. Od razu ostrzegam, że ponieważ kod jest przeróbką domyślnego szablonu, jest on delikatnie mówiąc „nieładny” i z pewnością będzie razić oczy purystów programowania. Natomiast mam nadzieję, że dla osób, rozpoczynających przygodę z ASP.NET Identity okaże się on przydatny i pozwoli im nie tracić całego dnia na kombinowanie „jak to wszystko poskładać”, tak jak to było w przypadku niżej podpisanego.
Odnośnik do kodu źródłowego: https://github.com/gashupl/aspnet-identity-dbfirst-approach