I am using NHibernate for persistence, but i read somewhere that NHibernate acts as unitofwork container. So do i need to create a separate UnitOfWork implementation. ?
Or continue with Nhibernate's unitofwork.
You don't need to create separate UoW implementation.
I suggest you to read this post: nhibernate.info
According to Martin Fowler, the Unit of Work pattern "maintains a list of objects affected by a business transaction and coordinates the writing out of changes and the resolution of concurrency problems."
Nhibernate internally already implements this pattern tracking all the objects has been modified (added,updated,deleted). You don't need to do anything because it already use this pattern itself
just to make this concept clear it is like if for each row of your resultset there is a "magic" column that says if the row has been added,updated or deleted
Related
I've seen the usage of gosu enhancements a lot within Guidewire application. However, it seems to me it is being overused. Like the following examples:
An entity querying another entity (i.e. looks to me an entity modeling problem).
An entity calling a webservice (i.e. its beyond the purpose of the entity).
Are there any recommended use cases when to use enhancements?
Yes, Enhancements are supposed to be used only for straight forward calculations which the business does not want to store in Database tables.
Instead of using the enhancements, I think its better to have a helper Gosu class Where we shall execute the complex queries and some logical calculations.
The recommended approach is that enhancements should be used to extend existing classes with new methods or properties closely related to the original class object.
I agree that enhancements seem to be overused, that is probably because its the easy way to add some logic in existing (OOTB) parts of the Guidewire system.
Your observations are totally valid. Enhancements should preferably be used for simple calculations where a permanent data model change is not required. Webservice calls and complex queries are recipes for performance issues when used inside an enhancement.
Enhancements can be used for standard getter/setter operations that could be obtained in a relatively straightforward calculation.
Let's assume that we have two simple domain objects :
Topic (entity) -> Messages (value object)
These two domain objects could be included into one aggregate according to DDD principles.
But in some cases we need to retrieve topics without messages (if want just show a list of topics) and sometimes we need to retrieve topics with messages.
What is the best way to design that simple case? Thanks in advance.
I would suggest you to separate domain logic from data needed for presentation. Something like Command-query separation (CQS) or command-query responsibility segregation (CQRS). For example, if someone adds a new message to topic, you create an appropriate command and handle it as a part of your domain logic. And if you need to display some data in user interface, you select only data that you really need through DTO (data transfer object). This solution avoids of unnessesary data retrieving and helps to keep simplicity. You retrieve only data you really need.
If this solution causes a lot of changes in your project, you can create an additional method in repository that returns a lightweight version of your aggregate (with default stub for Messages collection). But this solution has one drawback - you will need to keep in mind that this method returns incomplete data.
I'm facing several problems trying to apply DDD with EF4 (in ASP MVC2 context). Your advaice would be greatly appreciated.
First of all, I started to use POCO because the dependacy on ObjectContext was not very comfortable in many situations.
Going to POCO solved some problems but the experience is not what I was used to with NHibernate.
I would like to know if it's possible to use designer and to generate not only entities but also a Value Objects (ComplexType?). If I mean Value Object is a class with one ctor without any set properties (T4 modification needed ?).
The only way I found to add behavior to anemic entities is to create partial classes that extends those generated by edmx. I'm not satisfied with this approach.
I don't know how to create several repositories with one edmx. For now I'm using a partial classes to group methods for each aggregate. Each group is a repository in fact.
The last question is about IQueryable. Should it be exposed outside the repository ? If I refer to the ble book, the repository should be a unit of execution and shouldn't expose something like IQueryable. What do you think ?
Thanks for your help.
Thomas
It's fine to use POCOs, but note that EntityObject doesn't require an ObjectContext.
Yes, Complex Types are value objects and yes, you can generate them in the designer. Select several properties of an entity, right click, and choose refactor into complex type.
I strongly recommend putting business methods in their own types, not on entities. "Anemic" types can be a problem if you must maintain them, but when they're codegened they're hardly a maintenance problem. Making business logic separate from entity types allows your business rules and your data model to evolve independently. Yes, you must use partial classes if you must mix these concerns, but I don't believe that separating your model and your rules is a bad thing.
I think that repositories should expose IQueryable, but you can make a good case that domain services should not. People often try to build their repositories into domain services, but remember that the repository exists only to abstract away persistence. Concerns like security should be in domain services, and you can make the case that having IQueryable there gives too much power to the consumer.
I think it's OK to expose IQueryable outside of the repository, only because not doing so could be unnecessarily restrictive. If you only expose data via methods like GetPeopleByBirthday and GetPeopleByLastName, what happens when somebody goes to search for a person by last name and birthday? Do you pull in all the people with the last name "Smith" and do a linear search for the birthday you want, or do you create a new method GetPeopleByBirthdayAndLastName? What about the poor hapless fellow who has to implement a QBE form?
Back when the only way to make ad hoc queries against the domain was to generate SQL, the only way to keep yourself safe was to offer just specific methods to retrieve and change data. Now that we have LINQ, though, there's no reason to keep the handcuffs on. Anybody can submit a query and you can execute it safely without concern.
Of course, you could be concerned that a user might be able to view another's data, but that's easy to mitigate because you can restrict what data you give out. For example:
public IQueryable<Content> Content
{
get { return Content.Where(c => c.UserId == this.UserId); }
}
This will make sure that the only Content rows that the user can get are those that have his UserId.
If your concern is the load on the database, you could do things like examine query expressions for table scans (accessing tables without Where clauses or with no indexed columns in the Where clause). Granted, that's non-trivial, and I wouldn't recommend it.
It's been some time since I asked that question and had a chance to do it on my own.
I don't think it's a good practice to expose IQueryable at all outside the DAL layer. It brings more problems that it solves. I'm talking about large MVC applications. First of all the refactorings is harder, many developers user IQueryable instances from the views and after struggle with the fact that when resolving IQueryable the connection was already disposed. Performance problems because all the database is often queried for a given set of resultats and so on.
I rather expose Ienumerable from my repositories and believe me, it saves me many troubles.
Pros:
Repositories hide complex queries.
Repository methods can be used as transaction boundaries.
ORM can easily be mocked
Cons:
ORM frameworks offer already a collection like interface to persistent objects, what is the intention of repositories. So repositories add extra complexity to the system.
combinatorial explosion when using findBy methods. These methods can be avoided with Criteria objects, queries or example objects. But to do that no repository is needed because a ORM already supports these ways to find objects.
Since repositories are a collection of aggregate roots (in the sense of DDD), one have to create and pass around aggregate roots even if only a child object is modified.
Questions:
What pros and cons do you know?
Would you recommend to use repositories? (Why or why not?)
The main point of a repository (as in Single Responsibility Principle) is to abstract the concept of getting objects that have identity. As I've become more comfortable with DDD, I haven't found it useful to think about repositories as being mainly focused on data persistence but instead as factories that instantiate objects and persist their identity.
When you're using an ORM you should be using their API in as limited a way as possible, giving yourself a facade perhaps that is domain specific. So regardless your domain would still just see a repository. The fact that it has an ORM on the other side is an "implementation detail".
Repository brings domain model into focus by hiding data access details behind an interface that is based on ubiquitous language. When designing repository you concentrate on domain concepts, not on data access. From the DDD perspective, using ORM API directly is equivalent to using SQL directly.
This is how repository may look like in the order processing application:
List<Order> myOrders = Orders.FindPending()
Note that there are no data access terms like 'Criteria' or 'Query'. Internally 'FindPending' method may be implemented using Hibernate Criteria or HQL but this has nothing to do with DDD.
Method explosion is a valid concern. For example you may end up with multiple methods like:
Orders.FindPending()
Orders.FindPendingByDate(DateTime from, DateTime to)
Orders.FindPendingByAmount(Money amount)
Orders.FindShipped()
Orders.FindShippedOn(DateTime shippedDate)
etc
This can improved by using Specification pattern. For example you can have a class
class PendingOrderSpecification{
PendingOrderSpecification WithAmount(Money amount);
PendingOrderSpecification WithDate(DateTime from, DateTime to)
...
}
So that repository will look like this:
Orders.FindSatisfying(PendingOrderSpecification pendingSpec)
Orders.FindSatisfying(ShippedOrderSpecification shippedSpec)
Another option is to have separate repository for Pending and Shipped orders.
A repository is really just a layer of abstraction, like an interface. You use it when you want to decouple your data persistence implementation (i.e. your database).
I suppose if you don't want to decouple your DAL, then you don't need a repository. But there are many benefits to doing so, such as testability.
Regarding the combinatorial explosion of "Find" methods: in .NET you can return an IQueryable instead of an IEnumerable, and allow the calling client to run a Linq query on it, instead of using a Find method. This provides flexibility for the client, but sacrifices the ability to provide a well-defined, testable interface. Essentially, you trade off one set of benefits for another.
If my understanding of Aggregate Roots is correct, the root should be responsible also for deleting one of its "children". That would seemingly translate into something like this:
order.removeOrderLine(23);
Which would effectively remove it from the collection. However, how is this persisted? Is my ORM's UnitOfWork supposed to detect that something went missing in that collection, and then delete it from the database?
Should I have removeOrderLine a method of the OrderRepository instead?
Your Unit of Work should usually take care of this, but it depends on its implementation, specifically on the way it detects changes. Some unit of work implementations (i.e. Hibernate) keeps a copy of the aggregate before you changed it, so at the end of business transaction (when you call something like unitOfWork.PersistAll()), it tries to match current version of all objects (and collections) against the original version.
Other way is to have your domain entities more coupled with your unit of work so that the entity notified the unit of work when something changes (i.e. the order.removeOrderLine method would notify the unit of work about the change).
There are multiple ways how to implement UoW change detection. Have a look at several implementations for hibernat for inspiration.