I use partial view models all of the time when the 'partial' part is supposed to look the same between different pages. For example, if I have a list of items that may be displayed in the same way on several pages, I will have a partial view model (e.g. '_ListOfWhatevers.cshtml') that may use IList<Whatever>
as the model type upon which it is based. Then I will render that partial view with the appropriate list of items from my higher level views. So far I have not encountered a point where I wish I had not done it. It helps a lot with DRY when you have many pages showing the same type of data in slightly different contexts.
How large is your application? There's a good chance you're overthinking this. Unless the application is a large, enterprise-grade application, the high degree of loose coupling you are advocating is probably unnecessary.
If you decide that this level of loose coupling is still necessary, create a service layer that returns "service" objects. This fulfills a similar function to View Models in MVC. You will then write code in your service layer that maps objects from your domain model to your service model.
Note that part of your struggle may be due to the fact that, while your Data Repository is returning CRUD objects, your Service Layer should be returning the result of actions. For example:
public InvoiceView GetInvoice(int invoiceID);
returns a InvoiceView
object containing whatever data you wish to expose to the public, including Name, Address, Line Items and so forth, from several different tables/objects in your domain.
public class InvoiceView
{
public int InvoiceID;
public Address ShippingAddress;
public Address BillingAddress;
public List<LineItem> LineItems;
...
}
Similarly, there will be Service Layer methods that simply performs an action and returns an object indicating the result of the action:
public TransactionResult Transfer(
int sourceAccountID, int targetAccountID, Money amount, ValidationToken token);
IMPORTANT: You'll never be able to completely decouple from your data. Your consumer will always have to have some knowledge of the data, even if it's just an object ID or UUID.
Best Answer
First, you will run through every entity that you have and ask yourself :
What I mean here, is that in your object model, some entities are likely contained in others in a master-detail relationship. If your entity is highly dependant on another, do not create a repository for this entity alone because it won't likely be persisted by itself. Instead, you will create a repository for each parent class, and you will make sure that the child entities and other relations are persisted at the same time.
I don't like how they implemented the UnitOfWork pattern in the link you provided. I suggest you to do something more along these lines. You don't have to define one class per repository. The same class can be used for every repository, each having their own instance of the UnitOfWork class for the lifetime of the operation. You can also reuse the same UnitOfWork in different repositories for changes that you want persisted at the same time.