Just need to clarify this one, If I have the below interface
public interface IRepository<T>
{
T Add(T entity);
}
when implementing it, does checking for duplication if entity is already existing before persist it is still a job of the Repository, or it should handle some where else?
Yes - I recommend doing these checks in the repository.
Long answer: The term "repository" is a bit vague, but it is used more and more as the name of the persistence abstraction layer. The name is nice, but does not say too much: If you take Asp.Net MVC as an example, the sample apps, like Neirds dinner and alike, or codeplex projects encapsulate data access by the repository class. If such layer is implemented with a relational database for instancce, the primary keys of the tables will not allow duplicate entries, which means that in this case the repository implementation will throw an exception if 2 entries with the same key are inserted. So in other words, a RDBMS-implementation of a repository will quite always due this check, you wont be able to avoid it. So to make the behavior of repostories out there in the world most similar and to avoid surprises, lets all of them do this check.
It is a second question whether you should maintain in the business logic already that your Add() method is not alled with an entry that already exists. Sometimes it makes good sense to resolve this only at a single point, the database for instance, due to concurrency issues or savings of roundtrips. On the other hand it is for instance nice to tell the user as soon as possible that a username is already taken. So this depends.
have a nice day
If the entity already exists, you can either throw an exception, or update the existing entity's fields.
If you choose the latter, the method should probably be called something like AddOrUpdate()
Linq to SQL example
If I am retrieving a single record, I will use
public Entity GetEntity(int entityID)
{
return dataContext.Entities.SingleOrDefault(e => e.EntityID = entityID);
}
...And in the calling method, I will check to see if what is returned is null before attempting to use the returned entity.
If I am updating a record, I will retrieve the entity as shown, edit the entity, and then call an UpdateEntity(entityID) repository method to update the fields in the database.
If I am adding a record, it's even easier. Since this is a database, and my tables always contain an Identity field of type int (an auto-assignable number, essentially), adding a record is the simplest operation of all (it's always a new record):
Public void InsertEntity(Entity entity)
{
dataContext.Entities.InsertOnSubmit(entity);
dataContext.SubmitChanges();
}
Business rules (email addresses are unique, for example) can be handled in the repository, or in a separate business layer. If you are looking for the most "correct" way, I think most people would agree that business rules belong in their own Business Logic Layer.
Essentially the decision on where to handle that case depends on your exact requirements.
If you have business rules that define clear cut actions for when this happens, eg if a duplicate exists the new item should be renamed, then it can be built into the repository class.
On the other hand, if more complex rules are in place whereby, for example, more information is required to change the item before adding, then it should be handled further up the food chain.
The concept of a repository states that it exists to perform the persistence activities.
So if you can do it all within the repository, that's fine. If you find you start to reference outside the repository, or your repository has dependencies, eg calling another repository, or a service, or a manager (or whatever processor nomenclature you prefer), then it's a good sign to take it back a step.
Related
I've the following service operation in my ICustomerService:
public void RegisterCustomer(Customer customer)
{
Check.NotNull(customer, "customer");
//do another domain specific things...
customerRepository.Save(customer);
}
Edit
Customer class has an reference to ICollection<> of CustomerAddress entity.
This operation have to save customer address list too.
I know that do cascade updates does not is a good thing in this scenario:
How should I handle persistence for referenced entities?
From the DDD perspective, how should i do in this case?
Should i ask customer address list to the service operation through parameter?
I know that do cascade updates does not is a good thing in this
scenario:
Why ? As long as CustomerAddress is a simple entity and not an Aggregate Root, you have everything to gain by letting EF persist them along with the Customer.
Judging by your other question too, I think you may miss the Aggregate Root vs Entity distinction. This is where you should start -- design your aggregates, decide which objects should be AR's, simple Entities and Value Objects.
From there everything should fall into place according to some simple rules : one Repository per AR, Entities can only have references to Entities from the same Aggregate, it's better if an AR references another AR by its ID only, and VO's can be referenced from anywhere.
If you ask CustomerPhone, you can break (or not? it depends) invariant of Customer object. One of approaches is use Memento pattern. Extract internal state of your Customer to Memento object and pass this Memento to repository.
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.
I am learning DDD development for few days, and i start to like it.
I (think i) understand the principle of DDD, where your main focus is on business objects, where you have aggregates, aggregates roots, repositories just for aggregates roots and so on.
I am trying to create a simple project where i combine DDD development with Code First approach.
My questions are: (I am using asp.net MVC)
DDD Business Objects will be different than Code First objects?
Even if they will probably be the same, for example i can have a Product business object which has all the rules and methods, and i can have a Product code first (POCO) object which will just contain the properties i need to save in database.
If answer to question 1 is "true", then how do i notify the Product POCO object that a property from business object Product has been changed and i have to update it? I am using an "AutoMapper" or something like this?
If the answer is "no", i am completely lost.
Can you show me the most simple (CRUD) example of how can i put those two together?
Thank you
Update I no longer advocate for the use of "domain objects" and instead advocate a use of a messaging-based domain model. See here for an example.
The answer to #1 is it depends. In any enterprise application, you're going to find 2 major categories of stuff in the domain:
Straight CRUD
There's no need for a domain object here because the next state of the object doesn't depend on the previous state of the object. It's all data and no behavior. In this case, it's ok to use the same class (i.e. an EF POCO) everywhere: editing, persisting, displaying.
An example of this is saving a billing address on an order:
public class BillingAddress {
public Guid OrderId;
public string StreetLine1;
// etc.
}
On the other hand, we have...
State Machines
You need to have separate objects for domain behavior and state persistence (and a repository to do the work). The public interface on the domain object should almost always be all void methods and no public getters. An example of this would be order status:
public class Order { // this is the domain object
private Guid _id;
private Status _status;
// note the behavior here - we throw an exception if it's not a valid state transition
public void Cancel() {
if (_status == Status.Shipped)
throw new InvalidOperationException("Can't cancel order after shipping.")
_status = Status.Cancelled;
}
// etc...
}
public class Data.Order { // this is the persistence (EF) class
public Guid Id;
public Status Status;
}
public interface IOrderRepository {
// The implementation of this will:
// 1. Load the EF class if it exists or new it up with the ID if it doesn't
// 2. Map the domain class to the EF class
// 3. Save the EF class to the DbContext.
void Save(Order order);
}
The answer to #2 is that the DbContext will automatically track changes to EF classes.
The answer is No. One of the best things about EF code-first is that it fits nicely with DDD since you have to create your business objects by hand so do use your EF models to be equivalent to DDD entities and value objects. No need to add an extra layer of complexity, I don't think DDD recommends that anywhere.
You could even have your entities to implement an IEntity and you value objects to implement IValue, additionally follow the rest of DDD patterns namely Repositories to do the actual communication to the database. More of these ideas you can find this very good sample application in .NET, even though it doesn't use EF code first, it's still very valuable: http://code.google.com/p/ndddsample/
Recently I've done similar project. I was following this tutorial: link
And I've done it this way: I've created Blank solution, added projects: Domain, Service and WebUI.
Simply said in domain I've put model (for example classes for EF code first, methods etc.)
Service was used for domain to communicate with world (WebUI, MobileUI, other sites etc.) using asp.net webapi
WebUi was actually MVC application (but model was in domain so it was mostly VC)
Hope I've helped
The Pluralsight course: Entity Framework in the Enterprise goes into this exact scenario of Domain Driven Design incorporated with EF Code First.
For number 1, I believe you can do it either way. It's just a matter of style.
For number 2, the instructor in the video goes through a couple ways to account for this. One way is to have a "State" property on every class that is set on the client-side when modifying a value. The DbContext then knows what changes to persist.
Late question on this topic.
Reading Josh Kodroff's answer confirms my thoughts about the implementation of a Repository to, for instance, Entity Framework DAL.
You map the domain object to an EF persistance object and let EF handle it when saving.
When retrieving, you let EF fetch from database and map it to your domain object(aggregate root) and adds it to your collection.
Is this the correct strategy for repository implementation?
Scenario:
Retrieve some entities
Update some properties on those entities
You perform some sort of business logic which dictates that you should no longer have those properties updated; instead you should insert some new entities documenting the results of your business logic.
Insert said new entities
SaveChanges();
Obviously in the above example calling SaveChanges() will not only insert the new entities, but update the properties on the original entities. Before I have managed to rearrange my code in a way where changes to the context (and its entities) would only be made when I knew for sure that I would want all my changes saved, however that’s not always possible. So the question is what is the best way to handle this scenario? I don’t work with the context directly, rather through repositories, if that matters. Is there a simple way to revert the entities to their original values? What is the best practice in this sort of scenario?
Update
Although I disagree with Ladislav that the business logic should be rearranged in such way that the validation always come before any modification to the entities, I agree that the solution should really be persisting wanted changes on a different context. The reason I disagree is because my business transaction is fairly long, and validation or error checking that might happen at the end of the transaction are not always obvious upfront. Imagine a Christmas tree you're decorating with lights from the top down, you've already modified the tree by the time you're working on the lower branches. What happens if one of the lights breaks? You want to roll back all of your changes, but you want to create some ERROR entities. As Ladislav suggested the most straight forward way would be to save the ERROR entities on a different context, allowing the original one (with the modified metaphorical tree) to expire without SaveChanges being ever called.
Now, in my situation I utilize Ninject for dependance injection, injecting one EF context into all of my repositories that are in the scope of the top level service. What this means is that my business layer classes don't really have control of creating new EF contexts. Not only do they not have access to the EF context (remember they work through repositories), but the injection has already occurred higher in the object hierarchy. The only solution I found is to create another class that will utilize Ninject to create a new UOW within it.
//business logic executing against repositories with already injected and shared (unit of work) context
Tree = treeRepository.Get();
Lights = lightsRepsitory.Get();
//update the tree as you're decorating it with lights
if(errors.Count == 0)
{
//no errors, calling SaveChanges() on any one repository will commit the entire UOW as they all share the same injected EF context
repository1.SaveChanges();
}
else
{
//oops one of the lights broke, we need to insert some Error entities
//however if we just add id to the errorRepository and call SaveChanges() the modifications that happened
//to the tree will also be committed.
TreeDecoratorErroHandler.Handle(errors);
}
internal class TreeDecoratorErroHandler
{
//declare repositories
//constructor that takes repository instances
public static void Handle(IList<Error> errors)
{
//create a new Ninject kernel
using(Ninject... = new Ninject...)
{
//this will create an instance that will get injected with repositories sharing a new EF instance
//completely separate from the one outside of this class
TreeDecoratorErroHandler errorHandler = ninjectKernel.Get<TreeDecoratorErroHandler>();
//this will insert the errors and call SaveChanges(), the only changes in this new context are the errors
errorHandler.InsertErrors(errors);
}
}
//other methods
}
You should definitely use a new context for this. Context is unit of work and once your business logic says: "Hey I don't want to update this entity" then the entity is not part of unit of work. You can either detach the entity or create new context.
There is possibility to use Refresh method but that method is supposed to be used in scenarios where you have to deal with optimistic concurrency. Because of that this method refreshes only scalar and complex properties and foreign keys if part of the entity - if you made changes to navigation properties these can be still present after you refresh the entity.
Take a look at ObjectContext.Refresh with RefreshMode.StoreWins I think that will do what you want. Starting a new context would achieve the same thing I guess, but not be as neat.
In my ASP.NET MVC application I need to implement persistence of data. I've choose Entity Framework for its ability to create classes, database tables and queries from entity model so that I don't have to write SQL table creation or Linq to SQL queries by hand. So simplicity is my goal.
My approach was to create model and than a custom HttpModule that gets called at the and of each request and that just called SaveChanges() on the context. That made my life very hard - entity framework kept throwing very strange exception. Sometimes it worked - no exception but sometimes it did not. First I was trying to fix the problems one by one but when I got another one I realized that my general approach is probably wrong.
So that is the general practice to implement for implementing persistence in ASP.NET MVC application ? Do I just call saveChanges after each change ? Isn't that little inefficient ? And I don't know how to do that with Services patter anyway (services work with entities so I'd have to pass context instance to them so that they could save changes if they make some).
Some links to study materials or tutorials are also appreciated.
Note: this question asks for programing practice. I ask those who will consider it vague to bear in mind that it is still solving my very particular problem and right technique will save me a lot of technical problems before voting to close.
You just need to make sure SaveChanges gets called before your request finishes. At the bottom of a controller action is an ideal place. My controller actions typically look like this:
public ActionResult SomeAction(...)
{
_repository.DoSomething();
...
_repository.DoSomethingElse();
...
_repository.SaveChanges();
return View(...);
}
This has the added benefit that if an exception gets thrown, then SaveChanges will not get called. And you can either handle the exception in the action or in Controller.OnException.
It's going to be no more or less efficient than calling a stored procedure that many number of times (with respect to number of connections that need to be made).
Nominally, you would make all your changes to the object set, then SaveChanges to commit all those changes.
So instead of doing this:
mySet.Objects.Add(someObject);
mySet.SaveChanges();
mySet.OtherObjects.Add(someOtherObject);
mySet.SaveChanges();
You just need to do:
mySet.Objects.Add(someObject);
mySet.OtherObjects.Add(someOtherObject);
mySet.SaveChanges();
// Commits Both Changes
Usually your data access is wrapped by an object implementing the repsitory pattern. You then invoke a Save() method on the repository.
Something like
var customer = customerRepository.Get(id);
customer.FirstName = firstName;
customer.LastName = lastName;
customerRepository.SaveChanges();
The repository can then be wrapped by a service layer to provide view model objects or DTO's
Isn't that little inefficient ?
Don't prematurely optimise. When you have a performance issue, analyse the performance, identify a cause and then optimise. Repeat.
Update
A repository wraps data access, usually a single entity. A service layer wraps business logic and can access multiply entities through multiple repositories. It usually deals with 'slim' models or DTO's.
An example could be something like getting a list of invoices for a customer
public Customer GetCustomerWithInvoices(int id) {
var customer = customerRepository.Get(id);
var invoiceList = invoiceRepository.GetAllInvoicesFor(id);
return new Customer {
Customer = customer,
Invoices = invoiceList
};
}