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();
}
}
}
-
\$\begingroup\$ Where do you call Dispose() method of the BaseService? \$\endgroup\$Laserson– Laserson2016年10月15日 09:25:30 +00:00Commented Oct 15, 2016 at 9:25
1 Answer 1
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?