Concerning the contract between your domain and repository, I gather it is best to avoid an exciting-encompassing generic IRepository interface with techniques for example Create() and Remove()? Unless of course, obviously, it's natural to possess these techniques available for the organizations I am dealing with. That We imagine is really a rare scenario.
Rather, must i produce a fundamental IRepository contract with as numerous - possibly "as couple of" could be appropriate - common techniques (e.g., GetByID()) as is sensible? All databases could implement anything after which specialize.
Or is it more beneficial to visit the path of multiple specialized connects, à la ICreatable, IDeletable, IRetrievable, etc.?
I believe you need to only create an fundamental IRepository when the techniques inside the interface are utilized by all databases. For those who have some databases which will implement only an element of the techniques, than you need to choose the greater specialized connects.
Also the final option provides you with more versatility in adding behavior later for your repository if needed. If you are using the fundamental IRepository interface and also have to include a brand new approach to it, than you'll have to update all databases. If you are using the specialized version than you just update the databases that you need to apply this behavior.
I believe you need to use GenericRepository and Specs pattern. This really is help you save from making lots of specialized techniques in each repository.
I totally accept Gengzu. I have used this method in a number of projects as well as in my role like a solution architect I would like all designers within the team only write necessary and particular code. My experience is you the majority of the occasions desire a Remove and discover method etc. The instances where you wouldn't want this should not dictate. Effects is going to be the databases that require Remove will all need to implement this and will also be redundant code. Each one of these Remove techniques could rather happen to be implemented With a GenericRepository abstract class. That class can function against NHibernate and have a generic entity as T. Whenever you then are thinking about creating for instance a UserRepository it'll inherit from GenericRepository and IUserRepository. Where IUserRepository inherit from IRepository. I'll then add code:
public class UserRepository : GenericNHibernateRepository<User, int>, IUserRepository People public User GetUserByEmail(string email) Limitations.Eq("Email", email) var list = GetByCriteria(query) if (list.Count == ) return null else return list #endregion public interface IUserRepository : IRepository<User, int> public interface IRepository<T, ID> where T : IAggregateRoot Remove(T entity) void Flush()
What exactly re the advantages. You will find huge! As you can tell for IRepository interface we simply allow IAggregateRoot to possess a repository (a DDD guideline). All databases delete's is going to be named Remove (no developer will title it Remove etc. and it is only implementen at one place, the GenericNHibernate class). If your developer during my team are thinking about creating a brand new repository to have an entity the only real code is
public class CustomerRepositoryNHibernate : GenericNHibernateRepository, ICustomerRepository
Then you definitely get read, remove, find functiuons... take your pick. Pretty Good.
But another superb benefit in case your using Dependency Injection and IoC framework I'm able to just state that with for instance Windsor Castle you may create a facility that loads all databases that implement the IRepository interface and therefore are situated inside a assemebly (example MyProject.Infrastructure.Data). This provides you extremly boost for the team.
Firstly you developer produces a brand new repository in MyProject.Infrastructure.Data with online of code such as the example above.
Second at application startup Windsor Castle facility can make it readily available for injection. So that your developer can just continue writing a controller or service class that can take IComnpanyRepository as constructor parameter and it is all there.