Reputation: 459
A few days ago I decide to use Unit of work & Generic repository In my project. After a little search I found this solution to do this.
In this pattern we have 4 layer:
1. UI
2. Model
3. Repository
4. Service
The point is all domain models inheritance from Entity
class in model layer. For example :
public class Project : Entity<int> {
...
}
And this is my Entity
class:
public abstract class BaseEntity { }
public abstract class Entity<T> : BaseEntity, IEntity<T>
{
public virtual T Id { get; set; }
}
Now when I want to Add ApplicationUser
class to UoF pattern I get an error with this concept that ApplicationUser
is not inheritance from BaseEntity
.
Tip :
ApplicationUser
is inheritance fromIdentityUser
class
Whats the best practice to add ApplicationUser
to my design pattern?
UPDATE
I get the error message in IApplicationUserService
interface
public interface IApplicationUserService : IEntityService<ApplicationUser>
{
Task<Part> GetById(int? id);
}
IEntityService :
public interface IEntityService<T> : IService
where T : BaseEntity
{
void Create(T entity);
void Delete(T entity);
Task<List<T>> GetAllAsync();
IEnumerable<T> GetAll();
Task Update(T entity);
}
Upvotes: 1
Views: 595
Reputation: 22481
The IEntityService<T>
interface has a constraint so that each type that is provided as T
needs to be derived from BaseEntity
. As your ApplicationUser
class is derived from IdentityUser
, it cannot fulfill the constraint.
You can solve this in two ways:
BaseEntity
or Entity<T>
. This way, the contraint is not violated. The class could be named ApplicationUserEntity
or something like that. If you need to store an application user, you need to map the properties of the ApplicationUser
to the ApplicationUserEntity
. You might also think about whether you really need the ApplicationUser
class to be derived from IdentityUser
and derive it from BaseEntity
instead of creating a new class. BaseEntity
class it does not have any members. So you can easily substitute BaseEntity
by an interface, e.g. IEntity
. You use this interface wherever BaseEntity
is currently used, especially in the constraint. As a class can only be derived from one base class, but can implement several interfaces, you can implement IEntity
in ApplicationUser
so that you can use it as a type parameter for IEntityService<T>
. I'd favor the first approach as it avoids mixing authentication circumstances with persistence.
However, if you want to implement the second approach, first rename BaseEntity
to IEntity
, e.g. by accessing the context menu. This makes sure that the new name is used wherever BaseEntity
was used before. Then change
public abstract class IEntity { }
to
public interface IEntity { }
Upvotes: 3
Reputation: 35106
Solution to your question is not to try to push a square peg into a round hole. Answer this question for yourself: what good the generic repository will give you when applied to Identity part of your project?
I suspect there will be a lot of pain and swearing and a ton of custom code because ApplicationUserManager
probably won't work with your solution and you'll have to write a custom storage or at least partly implement some of the logic.
Just because there is a pattern, does not mean you have to apply it everywhere. Especially places where the pattern does not fit.
Upvotes: 0