I would an opinion about how you see the Repository pattern.
In the "old" Domain conception (for example from P of EAAA) the repository should be like an "in memory collection", so it should returns always the same type, so if you need a projection you have to make it out, so the projection will be made in the service layer for example, right? Or is possible to make it directly into the "Domain" project?
E.g.
public class CustomerRepository
{
//Constructor accepts an IRepository<Customer>
public IQueryable<Customer> GetAllDebtors()
{
//Use IRepository<Customer> here to make the query
}
}
Instead, in DDD, the repository, especially combined with CQRS, can return directly the projected type because the repository becomes a denormalization service, right?
E.g.
public class CustomerDenormalizer
{
//Constructor *could* accept an IRepository<Customer>
public IQueryable<Debtor> GetAllDebtors()
{
//Use IRepository<Customer> here to make the query and the projection
}
}
IMO, the correspondence with an "in-memory" collection is overemphasized. A repository shouldn't hide the fact that it encapsulates some heavy IO - that would be a leaky abstraction. Furthermore, IQueryable<T> is also a leaky abstraction since hardly any provider will support all the operations. I'd suggest delegating as much of the projecting as possible to the database, because it is quite good at it.
A projection in CQRS is somewhat different. It is usually implemented as an event consumer which updates a datastructure stored in some underlying storage mechanisms, which could itself be SQL server, or a key-value store. The central difference is that, in this case, a projection response to events from a message queue. These events could be coming from external systems.
Saying that the Repository in its "original form" has to return only objects of the same entity type is somewhat exaggerated. At all times people have been including Count() methods or other calculations in their Repositories for instance - and that's something that was documented even back in Evan's blue book.
On the other hand, I'm not sure what you mean by "denormalized types" but if that's types that borrow from several different entities to expose their data as is or consolidated, or expose partial views of single domain entities, I tend to think it's not the Domain any more. Oftentimes it turns out they serve application-specific purposes such as generating Excel reports or displaying statistics or summary screens.
If this is the case, and for performance reasons I want to leverage the DB directly instead of relying on the Domain, I prefer to create a separate project where I place all this "reporting" related logic. Never mind if you still name your data access objects Repositories in there (after all, they are also illusions of in-memory collections, only collections of other types).
In the "old" Domain conception (for example from P of EAAA) the repository should be like an "in memory collection", so it should returns always the same type, so if you need a projection you have to make it out, so the projection will be made in the service layer for example, right?
In my own solutions, I keep distinct the domain model (that is an C# expression of the language I learned from the domain expert, almost an internal DSL) and the applicative concerns related to the domain (such as repositories, that cope with the application need of persistence). This means that they are coded in different projects.
In such a structure, I've tried two different approaches: queryable repositories and custom ones.
Repositories that implement IQueryable have worked very well for developers using the domain to build UI or services exposed to third parties, but required a lot of work in infrastructure. We used different approaches on this side, from Linq2NHibernate to re-linq, each with pros and cons, but each one quite expensive. If you plan to use this technique, define good metrics to ensure that the time you save during application development worth the time you have to spend on custom infrastructure.
Custom repositories (those that expose methods returning IEnumerables) are much easier to design and implement, but they require more effort for UI and service's developers. We also had a case where using a custom repository was required by domain rules, since the query objects used to obtain results were specifications that were also part of the ubiquitous language and we were (legally) required to grant that the method used to query was the same used to express such value and predicate.
However, in custom repositories, we often expose projective methods too.
Or is possible to make it directly into the "Domain" project?
It's possible, but when you have many different (and very complex) bounded contexts to work with, it becomes a pain. This is why I use different projects for the domain classes expressing the ubiquitous language and the classes that serve applicative purposes.
Instead, in DDD, the repository, especially combined with CQRS, can return directly the projected type because the repository becomes a denormalization service, right?
Yes, they can.
That's what we do with custom repositories, even without CQRS. Furthermore, even with some repository implementing IQueryable, we occasionally exposed methods that produce projections directly.
Don't have generic Repository.
Don't have IQueryable.
Have ICustomerRepository.
Have your specific implementation of CustomerRepository leverage all the bells and whistles of the underlying storage system.
Have repository return projections.
public Interface ICustomerRepository
{
public IEnumerable< Customer> GetAllCustomer()
public IEnumerable< Debtor> GetAllDebtors()
public IEnumerable< CustomerSummary> GetCustomerSummaryByName(string name)
public IEnumerable< CustomerSummary> GetCustomerSummaryById(string id)
}
Related
What class in my project should responsible for keeping track of which Aggregate Roots have already been created so as not to create two instances for the same Entity. Should my repository keep a list of all aggregates it has created? If yes, how do i do that? Do I use a singleton repository (doesn't sound right to me)? Would another options be to encapsulate this "caching" somewhere else is some other class? What would this class look like and in what pattern would it fit?
I'm not using an O/R mapper, so if there is a technology out there that handles it, i'd need to know how it does it (as in what pattern it uses) to be able to use it
Thanks!
I believe you are thinking about the Identity Map pattern, as described by Martin Fowler.
In his full description of the pattern (in his book), Fowler discusses implementation concerns for read/write entities (those that participate in transactions) and read-only (reference data, which ideally should be read only once and subsequently cached in memory).
I suggest obtaining his excellent book, but the excerpt describing this pattern is readable on Google Books (look for "fowler identity map").
Basically, an identity map is an object that stores, for example in a hashtable, the entity objects loaded from the database. The map itself is stored in the context of the current session (request), preferably in a Unit of Work (for read/write entities). For read-only entities, the map need not be tied to the session and may be stored in the context of the process (global state).
I consider caching to be something that happens at the Service level, rather than in a repository. Repositories should be "dumb" and just do basic CRUD operations. Services can be smart enough to work with caching as necessary (which is probably more of a business rule than a low-level data access rule).
To put it simply, I don't let any code use Repositories directly - only Services can do that. Then everything else consumes the relevant services as interfaces. That gives you a nice wrapper for putting in biz logic, caching, etc.
I would say, if this "caching" managed anywhere other than the Repository then you are letting concerns leak out.
The repository is your collection of items. No code consuming the repository should have to decide whether to retrieve the object from the repository or from somewhere else.
Singleton sounds like the wrong lifetime; it likely should be per-request. This is easy to manage if you are using an IoC/DI container.
It seems like the fact that you even have consider multiple calls for the same aggregate evidences a architecture/design problem. I would be interested to hear an example of what those first and second calls might be, and why they require the same exact instance of your AR.
We have an ASP.NET MVC site that uses Entity Framework abstractions with Repository and UnitOfWork patterns. What I'm wondering is how others have implemented navigation of complex object graphs with these patterns. Let me give an example from one of our controllers:
var model = new EligibilityViewModel
{
Country = person.Pathway.Country.Name,
Pathway = person.Pathway.Name,
Answers = person.Answers.ToList(),
ScoreResult = new ScoreResult(person.Score.Value),
DpaText = person.Pathway.Country.Legal.DPA.Description,
DpaQuestions = person.Pathway.Country.Legal.DPA.Questions,
Terms = person.Pathway.Country.Legal.Terms,
HowHearAboutUsOptions = person.Pathway.Referrers
};
It's a registration process and pretty much everything hangs off the POCO class Person. In this case we're caching the person through the registration process. I've now started implementing the latter part of the registration process which requires access to data deeper in the object graph. Specifically DPA data which hangs off Legal inside Country.
The code above is just mapping out the model information into a simpler format for the ViewModel. My question is do you consider this fairly deep navigation of the graph good practice or would you abstract out the retrieval of the objects further down the graph into repositories?
In my opinion, the important question here is - have you disabled LazyLoading?
If you haven't done anything, then it's on by default.
So when you do Person.Pathway.Country, you will be invoking another call to the database server (unless you're doing eager loading, which i'll speak about in a moment). Given you're using the Repository pattern - this is a big no-no. Controllers should not cause direct calls to the database server.
Once a C ontroller has received the information from the M odel, it should be ready to do projection (if necessary), and pass onto the V iew, not go back to the M odel.
This is why in our implementation (we also use repository, ef4, and unit of work), we disable Lazy Loading, and allow the pass through of the navigational properties via our service layer (a series of "Include" statements, made sweeter by enumerations and extension methods).
We then eager-load these properties as the Controllers require them. But the important thing is, the Controller must explicitly request them.
Which basically tells the UI - "Hey, you're only getting the core information about this entity. If you want anything else, ask for it".
We also have a Service Layer mediating between the controllers and the repository (our repositories return IQueryable<T>). This allows the repository to get out of the business of handling complex associations. The eager loading is done at the service layer (as well as things like paging).
The benefit of the service layer is simple - more loose coupling. The Repository handles only Add, Remove, Find (which returns IQueryable), Unit of Work handles "newing" of DC's, and Commiting of changes, Service layer handles materialization of entities into concrete collections.
It's a nice, 1-1 stack-like approach:
personService.FindSingle(1, "Addresses") // Controller calls service
|
--- Person FindSingle(int id, string[] includes) // Service Interface
|
--- return personRepository.Find().WithIncludes(includes).WithId(id); // Service calls Repository, adds on "filter" extension methods
|
--- IQueryable<T> Find() // Repository
|
-- return db.Persons; // return's IQueryable of Persons (deferred exec)
We haven't got up to the MVC layer yet (we're doing TDD), but a service layer could be another place you could hydrate the core entities into ViewModels. And again - it would be up to the controller to decide how much information it wishes.
Again, it's all about loose coupling. Your controllers should be as simplistic as possible, and not have to worry about complex associations.
In terms of how many Repositories, this is a highly debated topic. Some like to have one per entity (overkill if you ask me), some like to group based on functionality (makes sense in terms of functionality, easier to work with), however we have one per aggregate root.
I can only guess on your Model that "Person" should be the only aggregate root i can see.
Therefore, it doesn't make much sense having another repository to handle "Pathways", when a pathway is always associated with a particular "Person". The Person repository should handle this.
Again - maybe if you screencapped your EDMX, we could give you more tips.
This answer might be extending out a little too far based on the scope of the question, but thought i'd give an in-depth answer, as we are dealing with this exact scenario right now.
HTH.
It depends on how much of the information you're using at any one time.
For example, if you just want to get the country name for a person (person.Pathway.Country.Name) what is the point in hydrating all of the other objects from the database?
When I only need a small part of the data I tend to just pull out what I'm going to use. In other words I will project into an anonymous type (or a specially made concrete type if I must have one).
It's not a good idea to pull out an entire object and everything related to that object every time you want to access some properties. What if you're doing this once every postback, or even multiple times? By doing this you might be making life easier in the short term at the cost of you're making your application less scalable long term.
As I stated at the start though, there isn't a one size fits all rule for this, but I'd say it's rare that you need to hydrate that much information.
I want to know how most people are dealing with the repository pattern when it involves hitting the same database multiple times (sometimes transactionally) and trying to do so efficiently while maintaining database agnosticism and using multiple repositories together.
Let's say we have repositories for three different entities; Widget, Thing and Whatsit. Each repository is abstracted via a base interface as per normal decoupling design processes. The base interfaces would then be IWidgetRepository, IThingRepository and IWhatsitRepository.
Now we have our business layer or equivalent (whatever you want to call it). In this layer we have classes that access the various repositories. Often the methods in these classes need to do batch/combined operations where multiple repositories are involved. Sometimes one method may make use of another method internally, while that method can still be called independently. What about, in this scenario, when the operation needs to be transactional?
Example:
class Bob
{
private IWidgetRepository _widgetRepo;
private IThingRepository _thingRepo;
private IWhatsitRepository _whatsitRepo;
public Bob(IWidgetRepository widgetRepo, IThingRepository thingRepo, IWhatsitRepository whatsitRepo)
{
_widgetRepo = widgetRepo;
_thingRepo= thingRepo;
_whatsitRepo= whatsitRepo;
}
public void DoStuff()
{
_widgetRepo.StoreSomeStuff();
_thingRepo.ReadSomeStuff();
_whatsitRepo.SaveSomething();
}
public void DoOtherThing()
{
_widgetRepo.UpdateSomething();
DoStuff();
}
}
How do I keep my access to that database efficient and not have a constant stream of open-close-open-close on connections and inadvertent invocation of MSDTS and whatnot? If my database is something like SQLite, standard mechanisms like creating nested transactions are going to inherently fail, yet the business layer should not have to be concerning itself with such things.
How do you handle such issues? Does ADO.Net provide simple mechanisms to handle this or do most people end up wrapping their own custom bits of code around ADO.Net to solve these types of problems?
Basically you want to utilize a UnitOfWork for this. I personally use NHibernate because their ISession interface is basically a Unit of Work, so it will batch together all commands and send them to the database together (there are additional smarts and object state tracking in there as well, which help with this). So the number of discrete commands sent to the database will depend on the life cycle of your ISession. In a web context I generally go with a Conversation Per Request, which means the ISession is created at the beginning of the request, and flushed (sent to the DB) at the end of the request.
There is a lot of potential here to change the life cycle of the session based on whether or not you need shorter or longer session, and you can also utilize transactions which can have a separate life cycle if you need to.
Consider that your abstracted repositories could be implemented in any number of databases: SQLite, Microsoft SQL Server, direct file access, etc -- even though you know that they are from the same database, it's not reasonable for "Bob" to attempt to make sure each repository can be transactionalized with respect to the other repositories.
Bob should perhaps talk to a DoStuffService that contains concrete implementations of your repositories. Since this service is creating concrete implementations of your repositories, it is capable of creating an appropriate transaction. This service would then be responsible for safely executing a UnitOfWork (thanks, ckramer) on behalf of Bob.
I am looking at implementing the repository pattern (since what I came up with was 90% an implementation of it anyway), and have come across a design question - where I have two or more core business objects (for example, Business and Contact in a CRM app), the BO's can be strongly related or not related at all.
In this situation, should I implement one repository (CrmRepository for example, with .addBusiness(), .addContact() et al), or multiple repositories (BusinessRepository, ContactRepository each with their own .add(), .delete() et al).
What is the best practice in this situation?
The underlying DAL is EF4.
Regards
Moo
We have been doing a lot of thinking recently at my work and came across a few articles that helped us visualize and design our repositories in a consistent manner.
From what we found out one of the better practices is to create one repository per aggregate root. An aggregate root would be an Entity type where you need to reference that entity type to reach child value types. Only an Entity type could be queried from the database and any child Value types would need to be traversed from the Entity.
With your information in your question it seems like a Business would be an aggregate root and thus an Entity Type and would require its own repository. Since Contact can live independently that might be an aggregate root as well. Both objects could have references to each other and use a repository to load up the Businesses from a Contact or Load up the Contacts from a Business via its respective repository.
I have been doing a lot of reading recently so i hope I made some sense in my thought process.
Some links
Aggregate Root
Entities, Value Objects, Aggregates and Roots
I totally agree with Mark on this, but to add a little more. As you look at the benefits of creating a Generic Repository, the common patter is IRepository and Repository. One thing I've found to be much more useful, brought to light by Jeremy D. Miller (can't find the reference) is having generics at the method level.
So my IReposity will have methods like this:
T FindByKey<T>(int key);
IEnumerable<T> FindAll();
T FindBy<T>(System.Linq.Expressions.Expression<Func<T, bool>> expression);
void Update<T>(entity);
Then, depending on your philosophy, you can pass around the Repository class and query it directly, or make your Repository implementation abstract and force it's use to be encapsulated by an explicit repository, like this:
CrmRepository : Repository
{
FindByCustomerId(int customerId)
{ return FindByKey<Customer>(customerId);}
}
how we can create a generic data access layer that can be used by any asp.net application using different datasource provider or webservices?
Can we create data access layer for application that consumes webservice?
You might look into the Repository Pattern. Repository is a facade that presents persisted objects as though they are in a collection in memory. Whichever provider you choose to get data is hidden behind the Repository interface.
IRepository with LINQ to SQL
Code Project Tutorial
A sample by Fredrik Kalseth
You have plenty of options! :-)
You mention you want to use the data access layer (DAL) from asp.net and web services. No problem.
Basically, what you need to figure out is a basic design you want to follow, and encapsulate the DAL into its own assembly which can be used / referenced from various consumers.
There are numerous ways of doing this:
create a Linq-to-SQL mapping for your tables, if you're using SQL Server as your backend, and use the Linq-to-SQL entities and methods
create a repository pattern (for each "entity", you have an "EntityRepository" class, which can be used to retrieve entities, e.g. EntityReposity.GetByID(int id), or EntityRepository.GetByForeignKey(string fk) or whatever
use some other means of accessing the data (NHibernate, your own ADO.NET based mapper)
you could actually also use webservice calls as your data providers
Your biggest challenge is to define a standard way of doing things, and sticking to it.
See some articles - maybe they'll give you an idea:
Creating a Data Access Layer in .NET - Part 1
Building a DAL using Strongly Typed TableAdapters and DataTables in VS 2005 and ASP.NET 2.0
Try the tutorials at www.asp.net:
DataAccess
Woah, there are a ton of resources out there. Best advice to start is to find a pattern that you feel comfortable with and stick to it for the project, there is nothing worse then changing your mind 3/4 the way in.
One that I have found and like to use is the Repository or Provider patter. The Repository pattern just makes sure you have standard access to repositories, like your store catalog or CMS system. You create an interface that in my case expose sets of IQueryable the object or the data model are just standard c# classes with now extra fluff POCO (Plain Old CLR Objects).
public interface ICMSRepository {
IQueryable<ContentSection> GetContentSections();
void SaveContentSection(ContentSection obj);
}
Then just implement the interface for your different providers, like a LINQ to SQL context, making sure to return the POCO objects as queryable. The nice thing about this is that you can then make extension methods off of the IQueryable to get what you need easily. Like:
public static IQueryable<ContentSection> WithID(this IQueryable<ContentSection> qry, int ID) {
return from c in qry select c;
}
//Allow you to chain repository and filter to delay SQL execution
ICMSRepository _rep = new SqlCMSRepository();
var sec = _rep.GetContentSections().WithID(1).SingleDefault();
The nice thing about using the Interface approach is the ability to test and mock it up or dependency inject your preferred storage at run time.
Another method I have used and is used in the ASP.Net framework a lot is the Provider model. This is similar except instead of an Interface you create a singleton abstract class, your implementations on top of the abstract class will then define the storage access means (XML, Flat file, SQL, MySql, etc). The base abstract class will be also be resonsible for creating it's singleton based on configuration. Take a look at this for more info on the provider model.
Otherwise you can look at this similar question.
IRepository of T is general good approach. This Interface should expose GetAll, GetByID, Insert, Delete and Submit methods.
But it's important to keep your business logic out of Repository class, and put it to custom logic/service class.
Also, if you return IQueriable in your GetAll method, what you can often see in various implementation of IRepository, UI layer can also query against that IQueriable interface. But querying of object graph should remain in Repository layer. There's a lot debate around this issue.
Look at using the Interfaces:
IDbConnection
IDbCommand
IDbDataAdapter
IdataReader