6
\$\begingroup\$

I am creating simple web api/ SPA application using EntityFramework, IUnitOfWork, Repository pattern, Unity DI along with Asp.net Identity.

Unity configuration

public static void RegisterTypes(IUnityContainer container)
        {
            // TODO: Register your types here
            container.RegisterType<DataContext>(new PerResolveLifetimeManager());
            container.RegisterType<IUnitOfWork, UnitOfWork>(new PerResolveLifetimeManager());
            container.RegisterType<IUserStore<User, Guid>, UserRepository>(new HierarchicalLifetimeManager());
            container.RegisterType<IUserRepository, UserRepository>(new HierarchicalLifetimeManager());
            container.RegisterType<IRoleStore<Role, Guid>, RoleRepository>(new HierarchicalLifetimeManager());
            container.RegisterType<IUserManager, ApplicationUserManager>(new HierarchicalLifetimeManager());
            container.RegisterType<IRoleManager, ApplicationRoleManager>(new HierarchicalLifetimeManager());
            container.RegisterType<IUserService, UserService>(new HierarchicalLifetimeManager());
        }

UnitOfWork

public class UnitOfWork : IUnitOfWork
    {
        protected DataContext _context = null;

        public UnitOfWork(DataContext context)
        {
            if (context == null)
            {
                throw new ArgumentNullException("Context argument cannot be null in UnitOfWork.");
            }

        this._context = context;
    }

    public void SaveChanges()
    {
        this._context.SaveChanges();
    }

    public async Task SaveChangesAsync()
    {
        await this._context.SaveChangesAsync();
    }

    public void Dispose()
    {
        if (this._context != null)
        {
            this._context.Dispose();
        }
    }
}

GenericRepository

public abstract class GenericRepository<T> : IGenericRepository<T>, IDisposable
      where T : class 
    {
        protected DataContext _context;
        protected readonly IDbSet<T> _dbset;

        public GenericRepository(DataContext context)
        {
            if (context == null)
            {
                throw new ApplicationException("DbContext cannot be null.");
            }

            _context = context;
            _dbset = context.Set<T>();
        }
//Other code ignored

}

UserRepository - implements IUserStore

public class UserRepository: GenericRepository<User>,IUserRepository
                {
                    public UserRepository(DataContext context)
                        : base(context)
                    {

                        if (context == null)
                            throw new ArgumentNullException("DbContext cannot be null.");

                        this._context = context;
                    }
    public async Task CreateAsync(User user)
            {
                this.CheckParamForNull(user, "User");

                this._context.Users.Add(user);
              await this._context.SaveChangesAsync();
            }        

        //Other Methods ignored for bravity

        }

ApplicationUserManager

public class ApplicationUserManager : UserManager<User, Guid>, IUserManager
    {
        public ApplicationUserManager(IUserRepository userRepository)
            : base(userRepository)
        {
            this.UserValidator = new UserValidator<User, Guid>(this)
            {
                AllowOnlyAlphanumericUserNames = false,
                RequireUniqueEmail = true
            };
            // Configure validation logic for passwords
            this.PasswordValidator = new PasswordValidator
            {
                RequiredLength = 6,
                RequireNonLetterOrDigit = true,
                RequireDigit = true,
                RequireLowercase = true,
                RequireUppercase = true,
            };

        }
    }

BaseService

public class BaseService
    {
        IUnitOfWork _unitOfWork = null;
        public BaseService(IUnitOfWork unitOfWork)
        {
            if (unitOfWork == null)
            {
                throw new ArgumentNullException("DbContext cannot be null.");
            }
        }

        public void Dispose()
        {
            if (this._unitOfWork != null)
            {
                this._unitOfWork.Dispose();
                this._unitOfWork = null;
            }
        }
    }

UserService

public class UserService : BaseService,IUserService
    {
        private IUserManager _userManager;
        private IUnitOfWork _unitOfWork;

        public UserService(IUserManager userManager, IUnitOfWork unitOfWork) 
            : base(unitOfWork)
        {
            _userManager = userManager;
            _unitOfWork = unitOfWork;

        }


        public async Task<IdentityResult> RegisterUser(CreateUserBindingModel usr)
        {
            var user = new User();

            user.Email = usr.Email;
            user.UserName = usr.Email;



       IdentityResult result = await _userManager.CreateAsync(user,usr.Password);
            _unitOfWork.SaveChanges();

            return result;
        }

    }

API UserController with Register method

namespace Angular.Api.Controllers
{
    [RoutePrefix("api/user")]
    public class UserController : ApiController
    {
        private IUserService _userService;


        public UserController()
        {

        }
        public UserController(IUserService userService)
        {
            _userService = userService;

        }


        [Route("Register")]
        public IHttpActionResult Register(CreateUserBindingModel usr)
        {



              _userService.RegisterUser(usr);



                return Ok();   



        }
    }
}
\$\endgroup\$
  • \$\begingroup\$ Where do you call Dispose() method of the BaseService? \$\endgroup\$ – Laserson Oct 15 '16 at 9:25
3
\$\begingroup\$

Looks pretty good, I will try this approach on my next project.

Just one question: Why do you use UnitOfWork AND Services?

You should as well be able to use only UnitOfWork and use all the Getters and Setters from there, or not?

Is this structure helpful when mocking?

When looking at the graphic here: from: http://www.asp.net/mvc/overview/older-versions/getting-started-with-ef-5-using-mvc-4/implementing-the-repository-and-unit-of-work-patterns-in-an-asp-net-mvc-application

It seems a little overhead, does it not?

\$\endgroup\$

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.