2
\$\begingroup\$

I created an application from 3 layers, DAL, BLL, and Representation layer in ASP.NET Web API. In DAL i have 4 Classes: - DatabaseContext.cs, UnitOfWork.cs, GenericRepository and UserInfo. In BLL i have a class called UserRepository that implemnet the IUserRepository interface. In the Representation Layer i have a controller called UserController. In this application Iam trying to use Identity. Following are the classes.

DatabaseContext.cs:

public class DatabaseContext : IdentityDbContext<UserInfo>
{
    public DatabaseContext() : base("DefaultConnection", throwIfV1Schema: false)
    {
        Configuration.ProxyCreationEnabled = false;
        Configuration.LazyLoadingEnabled = false;
    }

    public static DatabaseContext Create()
    {
        return new DatabaseContext();
    }
}

UnitOfWork.cs:

public class UnitOfWork : IDisposable, IUnitOfWork
{
    #region Private member variables...

    private DatabaseContext _context = null;
    private GenericRepository<UserInfo> _userRepository;

    #endregion

    public UnitOfWork()
    {
        _context = new DatabaseContext();
    }

    public T GetDbContext<T>() where T : DbContext
    {
        return this._context as T;
    }

    #region Public Repository Creation properties...

    /// <summary>
    /// Get/Set Property for user repository.
    /// </summary>
    public GenericRepository<UserInfo> UserRepository
    {
        get
        {
            if (this._userRepository == null)
                this._userRepository = new GenericRepository<UserInfo>(_context);
            return _userRepository;
        }
    }

    #endregion

    #region Public member methods...
    /// <summary>
    /// Save method.
    /// </summary>
    public void Save()
    {
        try
        {
            _context.SaveChanges();
        }
        catch (DbEntityValidationException e)
        {

            var outputLines = new List<string>();
            foreach (var eve in e.EntityValidationErrors)
            {
                outputLines.Add(string.Format(
                    "{0}: Entity of type \"{1}\" in state \"{2}\" has the following validation errors:", DateTime.Now,
                    eve.Entry.Entity.GetType().Name, eve.Entry.State));
                foreach (var ve in eve.ValidationErrors)
                {
                    outputLines.Add(string.Format("- Property: \"{0}\", Error: \"{1}\"", ve.PropertyName, ve.ErrorMessage));
                }
            }
            System.IO.File.AppendAllLines(@"C:\errors.txt", outputLines);

            throw e;
        }

    }

    #endregion

    #region Implementing IDiosposable...

    #region private dispose variable declaration...
    private bool disposed = false;
    #endregion

    /// <summary>
    /// Protected Virtual Dispose method
    /// </summary>
    /// <param name="disposing"></param>
    protected virtual void Dispose(bool disposing)
    {
        if (!this.disposed)
        {
            if (disposing)
            {
                Debug.WriteLine("UnitOfWork is being disposed");
                _context.Dispose();
            }
        }
        this.disposed = true;
    }

    /// <summary>
    /// Dispose method
    /// </summary>
    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }
    #endregion
}

GenericRepository.cs:

    public class GenericRepository<TEntity> where TEntity : class
{
    #region Private member variables...
    internal DatabaseContext Context;
    internal DbSet<TEntity> DbSet;
    #endregion

    #region Public Constructor...
    /// <summary>
    /// Public Constructor,initializes privately declared local variables.
    /// </summary>
    /// <param name="context"></param>
    public GenericRepository(DatabaseContext context)
    {
        this.Context = context;
        this.DbSet = context.Set<TEntity>();
    }
    #endregion

    #region Public member methods...
    /// <summary>
    /// generic Get method for Entities
    /// </summary>
    /// <returns></returns>
    public virtual IEnumerable<TEntity> Get()
    {
        IQueryable<TEntity> query = DbSet;
        return query.ToList();
    }

    /// <summary>
    /// Generic get method on the basis of id for Entities.
    /// </summary>
    /// <param name="id"></param>
    /// <returns></returns>
    public virtual TEntity GetByID(object id)
    {
        return DbSet.Find(id);
    }

    /// <summary>
    /// generic Insert method for the entities
    /// </summary>
    /// <param name="entity"></param>
    public virtual void Insert(TEntity entity)
    {
        DbSet.Add(entity);
    }

    /// <summary>
    /// Generic Delete method for the entities
    /// </summary>
    /// <param name="id"></param>
    public virtual void Delete(object id)
    {
        TEntity entityToDelete = DbSet.Find(id);
        Delete(entityToDelete);
    }

    /// <summary>
    /// Generic Delete method for the entities
    /// </summary>
    /// <param name="entityToDelete"></param>
    public virtual void Delete(TEntity entityToDelete)
    {
        if (Context.Entry(entityToDelete).State == EntityState.Detached)
        {
            DbSet.Attach(entityToDelete);
        }
        DbSet.Remove(entityToDelete);
    }

    /// <summary>
    /// Generic update method for the entities
    /// </summary>
    /// <param name="entityToUpdate"></param>
    public virtual void Update(TEntity entityToUpdate)
    {
        DbSet.Attach(entityToUpdate);
        Context.Entry(entityToUpdate).State = EntityState.Modified;
    }

    /// <summary>
    /// generic method to get many record on the basis of a condition.
    /// </summary>
    /// <param name="where"></param>
    /// <returns></returns>
    public virtual IEnumerable<TEntity> GetMany(Func<TEntity, bool> where)
    {
        return DbSet.Where(where).ToList();
    }

    /// <summary>
    /// generic method to get many record on the basis of a condition but query able.
    /// </summary>
    /// <param name="where"></param>
    /// <returns></returns>
    public virtual IQueryable<TEntity> GetManyQueryable(Func<TEntity, bool> where)
    {
        return DbSet.Where(where).AsQueryable();
    }

    /// <summary>
    /// generic get method , fetches data for the entities on the basis of condition.
    /// </summary>
    /// <param name="where"></param>
    /// <returns></returns>
    public TEntity Get(Func<TEntity, Boolean> where)
    {
        return DbSet.Where(where).FirstOrDefault<TEntity>();
    }

    /// <summary>
    /// generic delete method , deletes data for the entities on the basis of condition.
    /// </summary>
    /// <param name="where"></param>
    /// <returns></returns>
    public void Delete(Func<TEntity, Boolean> where)
    {
        IQueryable<TEntity> objects = DbSet.Where<TEntity>(where).AsQueryable();
        foreach (TEntity obj in objects)
            DbSet.Remove(obj);
    }

    /// <summary>
    /// generic method to fetch all the records from db
    /// </summary>
    /// <returns></returns>
    public virtual IEnumerable<TEntity> GetAll()
    {
        return DbSet.ToList();
    }

    /// <summary>
    /// Inclue multiple
    /// </summary>
    /// <param name="predicate"></param>
    /// <param name="include"></param>
    /// <returns></returns>
    public IQueryable<TEntity> GetWithInclude(
        System.Linq.Expressions.Expression<Func<TEntity,
        bool>> predicate, params string[] include)
    {
        IQueryable<TEntity> query = this.DbSet;
        query = include.Aggregate(query, (current, inc) => current.Include(inc));
        return query.Where(predicate);
    }

    /// <summary>
    /// Generic method to check if entity exists
    /// </summary>
    /// <param name="primaryKey"></param>
    /// <returns></returns>
    public bool Exists(object primaryKey)
    {
        return DbSet.Find(primaryKey) != null;
    }

    /// <summary>
    /// Gets a single record by the specified criteria (usually the unique identifier)
    /// </summary>
    /// <param name="predicate">Criteria to match on</param>
    /// <returns>A single record that matches the specified criteria</returns>
    public TEntity GetSingle(Func<TEntity, bool> predicate)
    {
        return DbSet.Single<TEntity>(predicate);
    }

    /// <summary>
    /// The first record matching the specified criteria
    /// </summary>
    /// <param name="predicate">Criteria to match on</param>
    /// <returns>A single record containing the first record matching the specified criteria</returns>
    public TEntity GetFirst(Func<TEntity, bool> predicate)
    {
        return DbSet.First<TEntity>(predicate);
    }
    #endregion
}

and the UserInfo class inherit from IdentityUser.

The class of the BLL is:

UserRepository.cs:

public class UserRepository : IUserRepository
{
    private readonly UnitOfWork _unitOfWork;
    private UserManager<UserInfo> _userManager { get; set; }
    public UserRepository()
    {
        _unitOfWork = new UnitOfWork();
        UserStore<UserInfo> store = new UserStore<UserInfo>(_unitOfWork.GetDbContext<DatabaseContext>());
        this._userManager = new UserManager<UserInfo>(store);
    }

    public async Task<IdentityResult> RegisterUser(UserEntity createUserModel)
    {
        UserInfo user = new UserInfo
        {
            FirstName = createUserModel.FirstName,
            LastName = createUserModel.LastName,
            UserName = createUserModel.UserName,
            Email = createUserModel.Email
        };
        var result = await _userManager.CreateAsync(user, createUserModel.Password);
        return result;
    }
}

}

and here is the controller :

    public class UserController : ApiController
{
    private UserRepository _repo = null;

    public UserController()
    {
        _repo = new UserRepository();
    }

    // POST api/User/Register
    [AllowAnonymous]
    [Route("Register")]
    public async Task<IHttpActionResult> Register(UserEntity userModel)
    {
        if (!ModelState.IsValid)
        {
            return BadRequest(ModelState);
        }

        IdentityResult result = await _repo.RegisterUser(userModel);

        IHttpActionResult errorResult = GetErrorResult(result);

        if (errorResult != null)
        {
            return errorResult;
        }

        return Ok();
    }

    private IHttpActionResult GetErrorResult(IdentityResult result)
    {
        if (result == null)
        {
            return InternalServerError();
        }
        if (!result.Succeeded)
        {
            if (result.Errors != null)
            {
                foreach (string error in result.Errors)
                {
                    ModelState.AddModelError("", error);
                }
            }
            if (ModelState.IsValid)
            {
                // No ModelState errors are available to send, so just return an empty BadRequest.
                return BadRequest();
            }
            return BadRequest(ModelState);
        }
        return null;
    }
}

These classes still missing the Unity implementation. i thought it might be good from you guys to help me to find out if there is something wrong with this architecture? and to find out how to implement The UserManager in UseRepository class. my idea is that i want to create a new class called AppUserManager that inherit from UserManager to configure some user proprety.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.