ASP.NET IdentityUser'ı diğer varlıklarımdan ayırma


11

ProjectName.CoreTüm iş mantığımı, varlıklarımı ve davranışlarını içeren bir kütüphanem var . Şu anda Entity Framework veya başka bir DAL ile herhangi bir ilişkisi yoktur, çünkü bunları ayrı tutmak istiyorum. Entity Framework yapılandırmaları (Akıcı API kullanarak) bir ProjectName.Infrastructureprojede yer alır, böylece varlıklarımı EF'e itmeye özen gösterir. Temelde Soğan benzeri bir mimari yönünde ilerliyorum.

Ancak, karışıma ASP.NET Kimlik çerçevesini eklerken, varlığımı sınıftan ApplicationUsermiras almam gerekiyor, IdentityUserancak ApplicationUsersınıfımın diğer varlıklar ile ilişkileri var. IdentityUserVarlık projemde Varlık Çerçevesine bir referans sunarken, bunu yapmak istemeyeceğim tek yer. Çekme ApplicationUserkişiler proje dışına ve içine sınıfını Infrastructurebu da bir yol değil yani (bir varlık Framework tabanlı kimlik sistemini kullanıyor beri) projesi, döngüsel başvurular ile sonuçlanacaktır.

ASP.NET Identity kullanmamanın yanı sıra iki katman arasındaki temiz ayrımı koruyabilmem için herhangi bir yol var mı?


1
Çekirdek projenizde bir IApplicationUser arayüzü oluşturamaz ve uygulamayı Altyapıda tutamaz mısınız? Bence, bir API oluşturmadığınız veya arayüz uygulamalarını çalışma zamanında değiştirmeniz gerekmedikçe, UI olmayan tüm kodlarınızı tek bir projede saklayın. Bir sürü farklı projeye sahip olmak, zihinsel ve kod yönetimi yükünüze çok fazla fayda sağlamaz.
mortalapeman

Yanıtlar:


12

Temel kitaplığınızdaki ASP.NET Identity ile ilgisi olmayan bir User sınıfı oluşturabilirsiniz .

public class User {
    public Guid UserId { get; set; }
    public string UserName { get; set; }
    public string EmailAddress { get; set; }
    public string EmailAddressConfirmed { get; set; }
    public string PhoneNumber { get; set; }
    public string PhoneNumberConfirmed { get; set; }
    public string PasswordHash { get; set; }
    public string SecurityStamp { get; set; }

    ...

    public virtual ICollection<Role> Roles { get; set; }
    public virtual ICollection<UserClaim> UserClaims { get; set; }
    public virtual ICollection<UserLogin> UserLogins { get; set; }
}

Entity Framework kullanıyorsanız, varlıklarınız için bir yapılandırma sınıfı oluşturun (isteğe bağlı).

internal class UserConfiguration : EntityTypeConfiguration<User>
{
    internal UserConfiguration()
    {
        ToTable("User");

        HasKey(x => x.UserId)
            .Property(x => x.UserId)
            .HasColumnName("UserId")
            .HasColumnType("uniqueidentifier")
            .IsRequired();

        Property(x => x.PasswordHash)
            .HasColumnName("PasswordHash")
            .HasColumnType("nvarchar")
            .IsMaxLength()
            .IsOptional();

        Property(x => x.SecurityStamp)
            .HasColumnName("SecurityStamp")
            .HasColumnType("nvarchar")
            .IsMaxLength()
            .IsOptional();

        Property(x => x.UserName)
            .HasColumnName("UserName")
            .HasColumnType("nvarchar")
            .HasMaxLength(256)
            .IsRequired();

        // EmailAddress, PhoneNumber, ...

        HasMany(x => x.Roles)
            .WithMany(x => x.Users)
            .Map(x =>
            {
                x.ToTable("UserRole");
                x.MapLeftKey("UserId");
                x.MapRightKey("RoleId");
            });

        HasMany(x => x.UserClaims)
            .WithRequired(x => x.User)
            .HasForeignKey(x => x.UserId);

        HasMany(x => x.UserLogins)
            .WithRequired(x => x.User)
            .HasForeignKey(x => x.UserId);
    }
}

Ayrıca Rol, UserClaim ve UserLogin için sınıflar oluşturmanız gerekir . Yukarıdaki adları beğenmezseniz, seçtiğiniz her şeyi adlandırabilirsiniz.

Web katmanında, AppUser (veya isterseniz başka bir ad) adlı bir sınıf oluşturun . Bu sınıf ASP.NET Identity IUser <TKey> arabirimini uygulamalıdır; burada TKey birincil anahtarın veri türüdür ( yukarıdaki örnekte Guid ).

public class AppUser : IUser<Guid>
{
    public AppUser()
    {
        this.Id = Guid.NewGuid();
    }

    public AppUser(string userName)
        : this()
    {
        this.UserName = userName;
    }

    public Guid Id { get; set; }
    public string UserName { get; set; }
    public string EmailAddress { get; set; }
    public string EmailAddressConfirmed { get; set; }
    public string PhoneNumber { get; set; }
    public string PhoneNumberConfirmed { get; set; }
    public string PasswordHash { get; set; }
    public string SecurityStamp { get; set; }
}

Web projesindeki UserManager'a yapılan tüm başvuruları UserManager <AppUser, Guid> olarak değiştirin .

Son olarak, kendi UserStore'unuzu oluşturun . Esasen, özel UserStore AppUser nesnesini alır, onu bir User varlık nesnesine dönüştürür ve sonra devam ettirir . Bu yöntemlerden birine bir örnek aşağıda gösterilmiştir:

public class UserStore : 
    IUserLoginStore<AppUser, Guid>, 
    IUserClaimStore<AppUser, Guid>, 
    IUserRoleStore<AppUser, Guid>, 
    IUserPasswordStore<AppUser, Guid>, 
    IUserSecurityStampStore<AppUser, Guid>, 
    IUserStore<AppUser, Guid>, 
    IDisposable
{
    private User MapFromAppUser(AppUser appUser)
    {
        if (appUser == null)
            return null;

        var userEntity = new User();

        PopulateUser(userEntity, appUser);

        return userEntity;
    }

    private void PopulateUser(User user, AppUser appUser)
    {
        user.UserId = appUser.Id;
        user.UserName = appUser.UserName;
        user.EmailAddress = appUser.EmailAddress;
        user.EmailAddressConfirmed = appUser.EmailAddressConfirmed;
        user.PhoneNumber = appUser.PhoneNumber;
        user.PhoneNumberConfirmed = appUser.PhoneNumberConfirmed;
        user.PasswordHash = appUser.PasswordHash;
        user.SecurityStamp = appUser.SecurityStamp;

        // First name, last name, ... 
    }

    #region IUserStore<AppUser, Guid> Members

    public Task CreateAsync(AppUser appUser)
    {
        if (appUser == null)
            throw new ArgumentNullException("appUser");

        var userEntity = MapFromAppUser(appUser);

        // Persist the user entity to database using a data repository.
        // I'll leave this to you.
    }

    ...

    #endregion
}

Olası bir uygulamanın tam tanımını almak için burayı tıklayın .

Sonunda, seçim senin. Bu uygulamayı sürdürmeniz için yalnızca Çekirdek kütüphanenizdeki Kimlik çerçevesine başvurmak için gereken çabayı ölçün. Şahsen, yukarıda tarif ettiğim şekilde yapmayı düşündüm, ancak ASP.NET Kimlik çerçevesi her güncelleştirildiğinde kodumu değiştirmek zorunda kalacağım için yapmadım.

Umarım bu yardımcı olur ve sorunuzu cevaplar!

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.