I am in the process of designing my data access code, the data is going to be stored in RavenDB, and I am trying to see if my current design has too much abstraction with the number of interfaces I am going to have.
I am going to have DTOs that will just hold the data and then I am going to have Entity (or Model, Business, or whatever you call them) objects that will have extra functionality. I am also going to have an interface per entity defining what data it needs to have. So for example:
interface IUser
{
string Id { get; }
string Username { get; }
string Password { get; }
bool ResetPassword { get; }
}
class UserDTO : IUser
{
public string Id { get; set; }
public string Username { get; set; }
public string Password { get; set; }
public UserDTO()
{
Id = null;
Username = null;
Password = null;
ResetPassword = false;
}
}
class User : IUser
{
public string Id { get; set; }
public string Username { get; set; }
public string Password { get; set; }
public User()
{
Id = null;
Username = null;
Password = null;
ResetPassword = false;
}
public User(IUser user)
{
Id = user.Id;
Username = user.Username;
Password = user.Password;
ResetPas开发者_StackOverflow中文版sword = user.ResetPassword;
}
public ResetPassword()
{
Id = null;
Username = null;
Password = null;
}
}
The reason I want to have an interface for each entity is because I want to make sure the both EntityDTO
and Entity
have the required shared data.
Now for retrieving and saving the data, I am going to use the repository pattern. I am going to have one generic interface called IDataRepository
and then each entity is going to have is own repository interface. For example:
interface IDataRepository<T>
{
bool Save(T entity);
bool Delete(T entity);
}
interface IUserRepository : IDataRepository<IUser>
{
IUser Load(string key);
IUser LoadByLogin(string username, string password);
}
class UserRepository : IUserRepository
{
bool Save(T entity)
{
//save code
}
bool Delete(T entity)
{
//delete code
}
IUser Load(string key)
{
//load code
}
IUser LoadByLogin(string username, string password)
{
//load code
}
}
The reason I want to have a repository interface for each entity is so that I can if I need to use different data storage options for different entities.
Do this seem like too much abstraction?
I think this model has its goods and bads. If your DTO is going to match the Entity, why have the DTO? In some systems this is something that needs to happen and in others it is a waste of time. Entities usually have baggage and dont serialize well depending on the ORM. If you use that interface the mapping between the DTO and Entity can be done with AutoMapper and should work well every time. Do you need to have the Entity class live in an separate DLL from the DTO? If so I think your model works.
Yes, this is too much abstraction. Specifically, I do not see a need for the UserDTO
class of objects.
IUser
itself should define the complete interface necessary for the data repository to do its job. If the repository is handed an object that implements IUser
, like User
for example, then it should be able to store the data just fine. And, since the interfaces are defined at the lowest level, omitting the UserDTO
object will not create any dependency problems.
What you have, in essence, seems fine to me.
However, unless you have further distinction between the DTO and Entity classes and a clear need to separate the two, I would simply have User
extends UserDTO
and remove the interface all together. That way, you remove the code redundancy that you currently have.
精彩评论