What is the name of the pattern in which every piece of data that the presentation layer gets and saves is as simple as possible with no ef context info attached?
eg.
CustomerManager manager = new CustomerManager();
Customer customer = manager.GetCustomerByEmail(string emailAddress);
DoSomething(customer);
manager.Save(customer);
And is this recommended for use in MVC? I see so many examples where controllers and view models are using ef contexts. It strikes me as bad practice.
PS. My reference to the "Clean Data" pattern was just my best guess and not a reference to an actual pattern.
I've never come across the "Clean Data" pattern.. but this looks more like the Active Record Pattern.
Generally when applying this pattern, your domain objects have Insert(), Update() and Delete() methods on them.
Its not often you see this approach these days. People tend to prefer keeping the persistence logic and business logic decoupled.. whereas this approach leads you down the path of them being very intertwined. This makes it harder to test and the codebase becomes resistant to changes.
The named pattern that I tend to use is the "repository" pattern, where the repository encapsulates the implementation details of how the data access layer is used. That way you can switch from EF (or whatever) without your controller-layer code needing to know about it.
http://martinfowler.com/eaaCatalog/repository.html
Related
I'm trying to build a repository layer for an application which interacts with 3 databases, all MSSQL. I made the repository structure is based on Dapper and Unit Of Work Pattern and looks like below:
Is this a good design? or what could be a better design for this?
I do not want to pass the connection instance from business, as it's not the job of a business layer; and should be of the data layer itself. Currently, am trying to manage the connection within the UnitOfWork class with the connection name and would like to change it.
EDIT: The design is not possible as it has multiple class inheritance, which is not possible in c#. Are there any alternate solutions?
There's very little info to work with here, but I'll try. It doesn't matter how many db you're using or their type. The repository with UoW is an anti pattern which becomes even worse with multiple dbs.
A repository should work with whole concepts (aggregates). I'm going the DDD route because is the easiest way to model things in an app. A repository will take care of one aggregate type. Its implementation will use dapper to work with the db.
If you need to modify multiple aggregates in one operation, first do make sure the business process is modeled properly (usually it's not). The business process itself is the UoW but this implies using Domain Events and a durable service bus (to be server crash resilient). And every message handler should be idempotent.
A repository should never know about other repos and the inheritance part is mostly a dubious design. The UoW inside the repo which enables the persistence of the whole aggregate regardless of how many objects it's made from, is the db transaction. Don't complicate your life with distributed transactions, keep a transaction per db.
That being said, it's obvious that a proper architecture (it has very little to do with the repository pattern, even less with dapper) needs someone with a lot of experience if you want a maintainable codebase. If you're a junior, ask a senior or take some time to learn DDD modelling properly. It's very easy to come up with 'solutions' that seem simple enough but are an unmaintainable mess.
Recently I have been reading up on using the repository pattern and DI to help create easily testable code, I think I understand it for the most part. However I'm having difficulty with one issue. I need to create a Rules object for my applications business layer. To create a rule, I need the ability to read and write to two tables. How would you go about implementing a repository that uses two tables for one object?
for example:
ICollection<type> GetAllRules();
What would I put in for type as it requires two tables?
Thanks
Steve
I wouldn't insist on having a repository for that.
As Fowler says
Conceptually, a Repository encapsulates the set of objects persisted in a data store and the operations performed over them, providing a more object-oriented view of the persistence layer.
This is probably why most implementations tend to expose pure domain objects rather than derivatives (which your Rule object seems to be).
I would have two repositories for the two tables you mention, then I would have a unit of work to expose all repositories and then I would have a business layer service responsible for the compound processing.
An advantage of such approach would be that the repository layer remains clean, there is no business processing involved here, no unclear rules introduced to the persistence layer.
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.
re: S#arp Architecture
A bit of a noob question about where to put certain sorts of domain logic with S#arp. OK, so imagine this domain rule:
When asking for a specific chat room by name, return the room if it already exists, or else create a new one with that name and return it.
Is this Domain Logic? In which case, how do I implement it in my Entity object (as I seem to need access to the Repository to do it)
Is this Controller Logic? In which case I guess I stick it in the MVC controller, easy enough.
Is this Data Access Logic? In which case I build it into the Repository object and the Contoller calls it. Again, easy enough.
I reckon this is Domain Logic, but then I'm not sure how to built it into my Entity. As Entities dont seem to access to Repositories (or am I missing something?).
From the way you've described it, I'd say this would best go in the Application Services layer. (the Tasks layer in the WhoCanHelpMe? example project). For me this is application logic rather than domain logic.
For the other options:
Sharp is designed intentionally so that Entities don't access the Repositories. (You'll find quite a lot of articles around on why Entities should be persistence-ignorant.)
In general the controllers aren't really meant to contain any business logic directly - for readability, testability, etc. (Personally I'm comfortable putting logic in there initially and then refactoring it out.)
One reason I'd be uncomfortable putting the logic directly in a repository is clarity. If you have methods on IChatRoomRepository:
ChatRoom GetRoomByName (string name);
ChatRoom GetRoomById (int id);
typically GetRoomById would return null if there is no room for the given id, so it's not too obvious that the first method will silently create (and presumably persist?) a room if you don't already have one.
More conceptually, from DDD Quickly (p56):
We should not mix a Repository with a Factory. The Factory should create new
objects, while the Repository should find already created objects. When a
new object is to be added to the Repository, it should be created first
using the Factory, and then it should be given to the Repository
which would suggest that if you're trying to implement the repository pattern, the creation of a new chat room should happen outside the repository.
We are currently revamping our architecture and design of application. We have just completed design of Data Access Layer which is generic in the sense that it works using XML and reflection to persist data.
Any ways now we are in the phase of designing business layer. We have read some books related to Enterprise Architecture and Design so we have found that there are few patterns that can be applied on business layer. Table Pattern and Domain Model are example of such patterns. Also we have found Domain Driven Design as well.
Earlier we decided to build Entities against table objects. But we found that there is difference in Entities and Value Objects when it comes to DDD. For those of you who have gone through such design. Please guide me related to pattern, practice and sample.
Thank you in advance! Also please feel free to discuss if you didn't get any point of mine.
#Adil, this is not an answer to your original question, but I would advise you to revise your decision to roll your own data access layer. You note that you'd like to go to NHibernate: just do it now.
IMO, writing an ORM is a waste of time unless you have some very specific restrictions. There are a wealth of options out there, with hundreds of hours of effort poured into them already. Leverage it! LINQ2SQL, Entity framework, NHibernate, Subsonic, LLBLGen are all good, and there are more out there.
Note too that if you roll your own you won't get to use the goodness that is LINQ without a lot of effort.
As far as layering goes, try not to go nuts: keep the number of layers in check and concentrate instead on building a worthwhile interface between them to guard against your abstractions leaking.
I've seen a number of very "patterned", beautifully layered projects that in use end up with logic everywhere and persistence abstractions leaked all over the place. Keep it simple!
CSLA.NET works pretty well as a base for the business layer.
#Adil,
I'm not very experient user, anyway, this is the kind of model I'm using (also with NHibernate).
GUI - with all the web forms and so on
BLL - The catalogs that are responsible for creating instances of new objects
DAL - The place where classes responsible for interaction with NHibernate are implemented. The NHibernate mapping files are here.
Model - Class Library that is used by the BLL and DAL for data transfer object between.
Different patterns are used. For example, the BLL and DAL have a Factory class that allow access to an interface. The catalogs are Singleton classes. All of the catalogs are accessible using a master Singleton class representing my business logic top object (for example "Enterprise" => "Enterprise.PeopleCatalog".
Anyway, hope it helped...
#AngryHacker, thanks for the tip, could you give an example of CSLA.NET?