Where do I put my mapping logic? - c#

I have a domain model, a repository and entity framework. I don't want my domain tied to EF or the persistence layer in general.
So I created a repository to keep things like db.Users.Where(u => u.Team == "MyTeam") out of my domain.
After implementing the generic repository pattern if I want a list of users on a particular team I use UserRepository.GetUsersByTeam("MyTeam").
The problem is my UserRepository is returning IEnumerable<EntityFrameworkUser>, instead of IEnumerable<DomainUser>, and in order to return IEnumerable<DomainUser> I need to map DomainUser to EntityFrameworkUser somewhere.
So where specifically do you map from the EntityFrameworkUser class to the DomainUser class?
Should the repository encapsulate the mapping logic in addition to the query logic?
If I want a collection of domain user objects what does the call stack look like for UserRepository.GetUsersByTeam("MyTeam") look like?
Searching has only found me general responses that usually quote Martin Fowler. I need a concrete example to refer to.

The problem is my UserRepository is returning an entity framework User DbSet
That shouldn't be the return type, because that would introduce coupling. You can still return that type, but it should be polymorphically interpreted as a different type.
So while you may be doing something like this in your repository:
return db.Users;
The return type shouldn't be that implementing type (DbSet<User>?), but something more generic:
public IQueryable<User> GetUsers()
{
return db.Users;
}
The "EF objects" are being used throughout the domain, but the domain doesn't know or care about that. The domain sees it as a queryable collection of User models.

If you want to keep domain object separately - keep them separately. If you repository returns objects from persistent layer, then it opens door for over-posting issues (it especially dangerous when front-end uses the same objects). I would move mapping logic into another class and use it in your repositories.
Automapper is very popular library for mapping different object, for example Domain object to DTO and vise versa. You can inject Automapper into your repositories and use it to map IEnumerable<EntityFrameworkUser> to IEnumerable<DomainUser>. First register mapping
Mapper.CreateMap<EntityFrameworkUser, DomainUser>();
Then call it from your repository
return Mapper.Map<IEnumerable<EntityFrameworkUser>, IEnumerable<DomainUser>>(users);

If the purpose of the method in question is simply to always return all of the members of the specified team, and you're never going to apply additional clauses to the result, you could change the return type of the UserRepostory.GetUsersByTeam() method from the EF DbSet<User> type to List<User>, then change the return statement to return db.Users.Where(u => u.Team == "MyTeam").ToList().
You'll no longer get the EF objects out of the repository level.

Related

Using Repository pattern - selecting specific fields of the entity for EF performance reasons

So, I am having a hard time with this Repository pattern. In lots of articles, posts and etc. I read that the repository should return only database objects(no DTOs, no mappers inside the repository).So you return single database object or list of objects.
This is OK, but for EF(entity framework) performance reasons, it's OK to return only field's that you need, not the entire entity.
So, how are you supposed to do that with repository pattern? You cannot select the database object with specific fields because it is detached
(ctx.Users.Select(new User(){ properties }).FirstOrDefault())
, you cannot return an anonymous object, and as I read it's not good practice to return IQueryable<User> and outside the repository to select desired fields.
Can you share some practice?
We solved it with 2 types of generic functions. You can either use
Automapper ProjectTo, which will define the mapping based on the generic type.
Write a custom selector expression to return an anonymous object. (You can return anonymous objects if you pass it on and return the same generic, that's also what the Select method's signature looks like)
In both cases the repository doesn't return the entity anymore, but it's also not responsible for for the transformation of the object, instead the Automapper library, or the caller with the select expression are taking care of that.

Repository pattern and localized lookup tables

I am trying to grabs the idea of the pattern repository and trying to get it implemented in database structures I've already set up in the past. I'm now trying to get the best practice to work with my lookup tables. I've created a test project to play around and this is my database model:
You can see that I have three tables for the lookups: Lookup, Language and LookupLanguage. Language table simply contains the languages.
Lookup tables holds the different types used throughout the models.
And LookupLanguage links the both tables together:
I've created anew project with all the models 1 to 1 to the database tables:
I also created a generic repository and a generic CrudService interface:
public interface ICrudService<T> where T : IsActiveEntity, new()
{
int Create(T item);
void Save();
void Delete(int id);
T Get(int id);
IEnumerable<T> GetAll();
IEnumerable<T> Where(Expression<Func<T, bool>> func, bool showDeleted = false);
void Restore(int id);
}
Now, according to the following post: When implementing the repository pattern should lookup value / tables get their own Repository? , the repository should hide the underlying database layer. So I think I need a new implementation of a service and/or repository to get the lookups, but then, where do I have to tell in which language I need to have the lookup?
Let's take the status (new, accepted, refused) from the company as an example.
The company model is as follow:
public partial class Company : IsActiveEntity
{
[Required]
[MaxLength(50)]
public string CompanyName { get; set; }
public System.Guid StatusGuid { get; set; }
[ForeignKey("StatusGuid")]
public virtual Lookup Status { get; set; }
}
I guess I don't need to have a separate implementation of a repository?
But I need a separate implementation CompanyService.
interface ICompanyService : ICrudService<Company>
{
IQueryable<LookupLanguage> GetStatuses(Guid languageguid);
LookupLanguage GetStatus(Guid statusguid, Guid languageguid);
}
Is this the correct approach, or do I miss something here?
Creating a Generic LookupRepository in your case in a better option because of your table schema and maintainence perspective.
I'm not sure whether you are using both Service Locator and Repository pattern or just Repository because of the name ICompanyService. But regardless, I agree that Repositories should not represent tables 1-1 always but they do most of the times.
The SO link you provided has a different table structure than yours. You have a generic lookup table vs the link has a separate table for each lookup. In the case where you have separate tables it makes sense to have the lookup repository method go with the entity repository since you will have a separate code to fetch the data for each lookup(as they have separate tables with different schema).
But in you case you have a single table that stores all the lookup types for each language and it makes sense to have a single LookupRepository that returns all the various types of lookups based on Language and LookupType. If you create each lookup method in separate entity repositories (like GetStatuses in CompanyRepository and GetStatuses in ContactRepository) you will have to repeat the logic in the method for each repository.
Think if you change the schema of the lookup table (say add a column) and you want to test all places the lookups are used it will be nightmare if you have lookup methods all over the place and pretty easy if you have one method in LookupRepository.
interface ILookupService : ICrudService<Lookup>
{
IQueryable<Lookup> GetStatuses(Guid languageguid, LookupType lookupType);
Lookup GetStatus(Guid statusguid, Guid languageguid, LookupType lookupType);
}
As regards your question, "Is this the correct approach" - this entirely depends on your specific needs.
What you have done doesn't seem to have any real issues. You have implemented the repository pattern using generics which is great. You are using interfaces for your repositories which allows for easier unit testing, also great!
One of your tags seems to indicate you are interested in the Entity Framework. You do not seem to be using that. The Entity Framework would simplify your code by creating the boiler plate classes for you. You can still use your repository pattern code with the classes created by the Entity Framework.
It seems that you are confusing the idea of a service and a repository. A repository is a general object which allows you to get data from a store without caring about the implementation. In your example, ICompanyService is a repository.
It is really controversial topic and there are different approaches to this problem. In our data logic we are not using repository pattern because we do not want to abstract most of the benefits of Entity Framework. Instead, we pass the context to the business logic which is already a combination of UoW / Repository pattern. Your approach is okay if you are going this way on all of your company services. However what I have seen so far, putting methods to the related services by their return values is the best approach to remind where they are. For instance if you want to get the company lookup, create a ILookupService and put GetLookUpsByCompany(int companyId) method to retrieve the company lookups.
I would argue with the linked response. Repositories ARE linked to database entities, considering the Entity Framework itself as a uow/repository implementation is a best example. On the other hand, services are for domain concerns and if there is a mismatch between your database entities and domain entities (you have two separate layers), services can help to glue the two.
In your specific case, you have repositories although you call them services. And you need a repository per database entity, that's just easier to implement and maintain. And also it helps to answer your question: yes, you need the extra repository for the linking table.
A small suggestion. You seem to have a generic query function that only accepts where clauses
IEnumerable<T> Where(Expression<Func<T, bool>> func, bool showDeleted = false);
If you already follow this route that allows arbitrary filtering expressions (which itself is a little arguable as someone will point out that you can' possibly guarantee that all technically possible filters can be executed by the database engine), why don't you allow all possible queries, including ordering, paging, etc:
IQueryable<T> Query { get; }
This is as easy to implement as your version (you just expose the dbset) but allows clients to perform more complicated queries, with the same possible concern that such contract is possibly too broad.
Localization is a presentation layer thing. The lower layers of your application should bother with it as little as possible.
I see two different kind of lookups: translations of coded concepts (Mr/Miss/Mrs) and translations of entity properties (company name maybe, or job titles or product names).
Coded concepts
I would not use lookup tables for coded concepts. There is no need to bother the lower layers at all with this. You will only need to translate them once for the entire application and create simple resource files that contain the translations.
But if you do wish to keep the translations in the database, a separate lookup repository for the codes or even per code system will sort of replace the resource file and serve you fine.
Entity properties
I can imagine different/nastier localization issues when certain entities have one or more properties that get translated in different languages. Then, the translation becomes part of the entity. I'd want the repository to cough up entity objects that contain all translations of the description, in a dictionary or so. Cause the business layer should not worry about language when querying, caching and updating relations. It should not ask the company repository for the Dutch version of company X. It should simply ask for company X and be served a Company object that contains its name in Dutch, English and French.
I've one more remark about the actual database implementation:
I think the lookup tables are distracting from the actual entities, to the point where you have forgotten to create a relation between person and person company. ;) I'd suggest putting all translations of entity properties in a single XML type column instead.
This illustrates why the repository should handle entities plus translations. If you were to make this storage layer level implementation change at some point, i.e. go from lookup tables to xml columns, the repository interfaces should remain the same.

How can I decouple the EF POCO from the generic IRepository in this pattern?

I currently have a Repository/UnitOfWork pattern down. However, there is one hard coupling that I am unable to figure out how I can get rid of.
This is an overview of my pattern:
Business Logic Layer
IRepository
Used as type contraint
IRepository< TModel, TDTO >
Implements IRepository
General CRUD methods
IEmployeeRepository< TModel >
Implements IRepository< TModel, EmployeeDTO >
Some employee specific methods
IUnitOfWork
Getter for repositories
Save method
IEntityWithId
Interface to force (and expose) DTOs and EF POCOs to have a Int32 field called ID
Used as type contraints
EmployeeDTO (Mapped with AutoMapper in the implemented EmployeeRepository)
DTO entity used in the core project and (to come) test project
Data Layer (Injected with Ninject)
UnitOfWork
Implementation of IUnitOfWork based on Entity Framework
EmployeesRepository
Implementation of IEmployeeRepository< TModel >
Employee
EF POCO
Core
EmployeesController
Parametered constructer EmployeesController(IUnitOfWork unitOfWork)
IUnitOfWork is injected with a Ninject module as a UnitOfWork (from Data layer)
Those are the problem methods in my generic IRepository interface.
TDTO Find(Expression<Func<TModel, bool>> filter);
and
IEnumerable<TDTO> FindAll(Expression<Func<TModel, bool>> filter);
As you can see, there is TModel in there, which is used to build up an expression to filter results. I COULD do something like using an expression on the DTO, but that would require a complete list of employees mapped to DTOs (aka it wouldnt generate a SQL filter but it would filter a SELECT * FROM Employee result list). So this isn't a good option.
The other, more viable but not optimal solution is to use dynamic LINQ. That way, I can pass a simple string in the Find / FindAll methods and get rid of the TModel requirement. However, this would means that refactoring becomes annoying since it fills the code with magic strings.
Just as I posted this, I think I figured out where my problem is.
Find() and FindAll() shouldn't even exist. I should write more specific methods like FindEmployeeByName(string name) in the IEmployeeRepository, then implement it like so :
EmployeeDTO FindEmployeeByName(string name)
{
return Mapper.Map<EmployeeDTO>(dbSet.Where(o=>o.name.Contains(name)).FirstOfDefault());
}
Can anyone confirm this is a proper way to do it? Or suggest something even better?
Edit
Also, if I want to keep Find(Expression...) and FindAll(Expression...) methods, I can, but they are just in the Data layer and used by implemented methods to avoid repeated code. But they should not be used in controllers as they requires knowledge of the underlaying data structure, beyond my Business Logic. That said, they can be implemented in a BaseRepository< TModel > (That I already have but did not mention to keep things more simple) and make EmployeesRepository an extention of BaseRepository. That way, every Repository already have those generic-like method that are Model-Aware.
Not sure if I explained that properly. Let me know if it's unclear and I'll try to edit this and make it better.
Another way to do this is to make your data layer depend on the business layer and have your repository "project" entities into your business objects (DTO's). This way your BL is at the bottom and UI and Data depend on it, but UI and Data do not depend on each other.
This is the method espoused by Mark Seemann in his book on Dependency Injection.

Advice on Linq to SQL mapping object design

I hope the title and following text are clear, I'm not very familiar with the correct terms so please correct me if I get anything wrong. I'm using Linq ORM for the first time and am wondering how to address the following.
Say I have two DB tables:
User
----
Id
Name
Phone
-----
Id
UserId
Model
The Linq code generator produces a bunch of entity classes.
I then write my own classes and interfaces which wrap these Linq classes:
class DatabaseUser : IUser
{
public DatabaseUser(User user)
{
_user = user;
}
public Guid Id
{
get { return _user.Id; }
}
... etc
}
so far so good.
Now it's easy enough to find a users phones from Phones.Where(p => p.User = user) but surely comsumers of the API shouldn't need to be writing their own Linq queries to get at data, so I should wrap this query in a function or property somewhere.
So the question is, in this example, would you add a Phones property to IUser or not?
In other words, should my interface specifically be modelling my database objects (in which case Phones doesn't belong in IUser), or are they actually simply providing a set of functions and properties which are conceptually associated with a User (in which case it does)?
There seems drawbacks to both views, but I'm wondering if there is a standard approach to the problem. Or just any general words of wisdom you could share.
My first thought was to use extension methods but in fact that doesn't work in this case.
I've had some awful experiences trying to abstract LINQtoSQL entities behind interfaces. It was a while ago, but from memory the main problem was that it totally breaks associations. For example, if you have a Customer -> Order relationship, you end up exposing it as an ICustomer, with a collection of IOrders, which means that Customer has to do some awkward mapping to cast it's internal collection of Order objects as IOrders.
Then you have to assume that when an IOrder gets passed back in, that we can cast it to an Order. Otherwise LINQtoSQL can't deal with it, but then that defeats the point of having the interface there in the first place.
I would strongly recommend that you don't try and abstract away the entity classes too much, LINQtoSQL doesn't actually put any real magic in them, the DataContext handles their persistence lifecycle, so they remain testable.
The aspects that I would be looking to hide behind an interface would be the interactions with DataContext, for example using Repository-style classes:
public interface IPhoneRepository
{
IEnumerable<Phone> GetPhonesForUser(User user);
}
public class L2SPhoneRepository : IPhoneRepository
{
private readonly MyDataContext context;
public L2SPhoneRepository(MyDataContext context)
{
this.context = context;
}
public IEnumerable<Phone> GetPhonesForUser(User user)
{
return context.Phones.Where(p => p.User == user);
}
}
Your interface should model how you would like for the objects to be used. Since you are trying to abstract, then the consumer should not have to query the DB. Whether you make it a property, or a separate function call (ie, GetPhones()), is entirely up to you. Since you are completely wrapping things, you'll have to make some choices about how deep/lazily you want to load your objects.
You should add Phones property to IUser and make it nullable, so for a User who don't have Phone, it will be null.
Since you don't want consumers of the API to write queries, than you should implement functions like GetUser().. etc.
Here is a nice list of article abt n-tier application in Asp.net
http://imar.spaanjaars.com/QuickDocId.aspx?quickdoc=416
I tend to consider the Linq2Sql related stuff to be an implementation detail of the data access code and, like the real structure of the database, shouldn't necessarily be exposed to other parts of the system.
If your API is going to be consumed by other people it should be cohesive and easy to use and not cluttered by things the consumer doesn't need to know about. If I'm dealing with users and their phones I don't really want to know about DataContexts or (ugh) DataSets.
Also, by keeping the bulk of your code ignorant of the L2S and database you will have an easier time testing, making schema changes (oh, so now the User table needs to keep a history of every change made) or even changing the ORM completely.

ASP.NET MVC: How many repositories?

I am in the process is designing a website in ASP.NET MVC and am perhaps a little confused as to the exact nature of a repository.
Following the NerdDinner example, my site should have one repository which serves up the entities as I need them. However, I have also heard that you should have different repositorys that deal with specific sets of related entities....?
In the case of my site, there will be a number of entities (around 15 tables) yet the majority are all related. Is it ok / advisable to have one repository that contains all the methods that I'll need for pulling / updating / deleting etc or should I split them down?
I use a generic repository which is plenty for many entities.
For a more complex one, I simply extend this with what's needed. The best of both worlds really.
In domain driven design, there's a rule that repositories are per aggregate root. You can read more about it here.
The more I read, the more I think that NerdDinner is too often seen as a collection of good practices, while it's absolutely not (see here for a discussion of, particularly, NerdDinner repository). That's why people often blame other MS examples like Oxite (and here:
Developers will flock to it, praise
it, and blindly accept it as gospel
because it comes from Microsoft (it's
already well on its way). Sadly, any
developer which adopts its spirit will
be left with an unmaintainble,
untestable and unreadable mess
).
If you use a generic repository which accepts types then I don't see any reason to use more than one.
we use an interface like this:
public interface IRepository
{
void Save<ENTITY>(ENTITY entity)
where ENTITY : Entity;
void Delete<ENTITY>(ENTITY entity)
where ENTITY : Entity;
ENTITY Load<ENTITY>(int id)
where ENTITY : Entity;
IQueryable<ENTITY> Query<ENTITY>()
where ENTITY : Entity;
IList<ENTITY> GetAll<ENTITY>()
where ENTITY : Entity;
IQueryable<ENTITY> Query<ENTITY>(IDomainQuery<ENTITY> whereQuery)
where ENTITY : Entity;
ENTITY Get<ENTITY>(int id) where ENTITY : Entity;
IList<ENTITY> GetObjectsForIds<ENTITY>(string ids) where ENTITY : Entity;
void Flush();
}
then use in code like this:
var returnedObjects = repository.GetAll<ObjectClass>();
var singleObject = repository.Get<ObjectClass>(id);
I create a repository for each data object.
For example, a simple library database could contain the following repositories:
AuthorRepository
BookRepository
PublisherRepository
I think perhaps the verbiage of what is a repository might be confusing you. To me a repository is the data storage (ie; MS SQL Database) of where your data is being stored into.
Following the Repository Pattern I recommend setting up a single respository for each datastore. Most of my projects I use MS SQL so I create a Repository for that DB (I like using Subsonic for my DAL/ORM and it also implements the Repositry pattern and the ActiveRecord pattern) then I create Factories for each table. This lets me wrap up the Subsonic ActiveREcord classes and gives me abstraction.
Hope thats helpfull, perhaps...
You should not create Repositories per each table. As queen3 said, you should create Repository per aggregate root. Like, if Products can have a Category, Category Repository should be a nested class of Products. Follow the domain logic relationship than domain objects.
Queen3 is right, you can follow that Aggregate Root theory. I basically group my repository not thinking in Entities but how they group logically in the application I'm building.
For example:
CustomersRepository
OrdersRepository
...
In CustomerRepository I would put methods for GetCustomers, GetCustomer, AddCustomer, DeleteCustomer, AddCustomerContact, DeleteCustomerContact.
In OrdersRepository I would put methods for GetOrders, GetOrder, AddOrder, CancelOrder, CloneOrder, AddOrderDetail, DeleteOrderDetail and so on.
I tend to use a repository per related group of entitites. i.e orderrepository might have:
Order, and OrderDetail.
and would have another for, say, Customer, CustomerProfile, etc.
This keeps the repository classes neat.
Davy

Categories

Resources