I am creating a solution in ASP.NET MVC 2, NHibernate and DDD. I am using a semi CQRS type Model.
ASP.NET Controller send validated messaged to Service Layer which updates state of an Domain object.
I have my Domain Dispatch "Events" and these are then caught by "Event Handlers" who act on them. Each of these Event Handler have access to Repository Layer and can commit an Domain Object State.
Event Handlers also insert records directly into reporting based tables using a (non NHibernate ) Repository. Event Handlers may also do non database related operations like sending emails.
Event Handler can also change state of an object thereby creating new set of events.
How can I assure that all database operation that occur during a single asp.net Request are inside a single Transaction.
I have been reading some blogs ( like Kevin Williams , Matt Wrock and Davy Brion) and have got information on how to start a Session object in Begin and End Request ( Again I will be using Structure Map here) but not sure how the transaction is maintained. This was compounded by the fact that start and end Requests may be called on different threads.
My Repository Class takes NHibernate ISession in its Parameter. If I create ISession as Hybrid Scope ( StructureMap) will that ensure that during a request ISession parameter that is passed by StructrueMap remain same.
Please advise and also let me know if my question is not clear.
Thank you,
Mar
The Mar
You can consider implementing the Unit Of Work pattern for each web request. The unit of work creates an NHibernate session and also handles transactions. There are several implementations that you can find on the web such as this and this.
in addition to WorldIsRound's answer- you haven't specified in your description where transactions are created and commited (from your explanation i'm assuming it should be somewhere in the Service layer).
I konw that there are tools that'll manage your sessions, and maybe your transactions, for you, but in my opinion, you want to explicitly control your transactions.
I use UOW pattern in my projects as well, to create a Session object in the Begin_Request event, and then I use that object to create transactions when I need them.
Again, that's just my opinion, but I think you should have complete control over opening and closing your transactions.
Good luck
Related
I am building an ASP.NET application using nhibernate and I implemented the session per request architecture. Each request I am opening a session, using it, then closing it. I am using one large object across several views and I am storing the object in user session cache so it maintains state for them across several different pages. The users do not want to have to save their changes on each page, they want the ability to navigate between several pages making changes, then commit them to the DB. This works well except for when the users try to hit a page that triggers lazy loading on the proxy object (which fails due to the session per request design closing the nhibernate session in the previous request). I know that turning lazy loading off would fix it; however, that is not an option due to the performance issues it would cause in other areas. I have tried changing the session per request design but have had no luck since I do not know when it is "safe" to close the nhibernate session.
Has anyone else done anything similar to this or have any advice?
Thanks in advance!
Keeping any objects in user session - the server session, server resource is not the best approach. Just imagine, that accidently your application will be very very successful... and there will be many users... therefore many sessions == many resources.
I would suggest (based on some experience), try to re-think the architecture to avoid session. Extreme would be to go to single page application... but even some async during "...navigation among several pages..." will be better.
All that will mean, that:
we passs data to client (standard ASP.NET MVC way with rendered views or some Web Api JSON)
if needed we send data back to server (binding of forms or formatting JSON)
In these scenarios, standard NHiberante session will work. Why? Because we "reload and reassign" objects with standard NHibernat infrastructure. That would be the way I suggest to go...
But if you want to follow your way, then definitely check the merge functionality of NHibernate:
9.4.2. Updating detached objects
9.4.3. Reattaching detached objects
19.1.4. Initializing collections and proxies
Some cites:
In an application with a separate business tier, the business logic must "prepare" all collections that will be needed by the web tier before returning. This means that the business tier should load all the data and return all the data already initialized to the presentation/web tier that is required for a particular use case. Usually, the application calls NHibernateUtil.Initialize() for each collection that will be needed in the web tier (this call must occur before the session is closed) or retrieves the collection eagerly using a NHibernate query with a FETCH clause or a FetchMode.Join in ICriteria. This is usually easier if you adopt the Command pattern instead of a Session Facade.
You may also attach a previously loaded object to a new ISession with Merge() or Lock() before accessing uninitialized collections (or other proxies). No, NHibernate does not, and certainly should not do this automatically, since it would introduce ad hoc transaction semantics!
I just finished watching John Pappa's pluralsight training video and was just blown away with how all of the pieces came together.
As I am digesting what I learned I am left with one serious after thought.
As incredibly easy breeze makes the queryable part and the CUD part of data services, the CUD part seems to have too much of a proprietary webapi method signature. It's easy to use and brilliant in how functional it is for its simplicity but we are used to Post, Put and Delete for the CUD part of things. These individual WepApi methods are more to code but they allow explicitly stated logic for saving things. I, for example, only do soft deletes, so an explicitly declared Delete webapi function would allow me to insert a deleted record in to my audit table, mark the record deleted by setting the DeletedDate and then actually not delete the record. Sometimes, based on the role of the person, you want to do overposting protections. For example CreatedDate might be a property in the entity but a client side forced/invalid change in that property should not auto-update the column on the server side. Or, while part of a ServiceTicket entity, the assigned service technician should never be able to be updated by the client unless the user has certain roles.
Where and how can these server side interventions be coded in the SaveChanges method in breeze? And what happens when people expect a fully Post/Put/Delete like "api" and breeze only provides a single method like SaveChanges?
And finally I am assuming that breeze uses the proprietary ContextProvider only because the odata implementation doesn't yet do the expand and select, right? Are there any plans to do away with that extra layer if and once wepapi odata fully implements all the odata verbs? How, if at all, has the 2012 Update 2 changed things in this regard?
Thanks
My use case is as follows:
Managing orders with order lines, a customer and payment details.
The app consists of an order list view from which an order detail view can be opened for editing an existing order or creating an new order. The order detail view uses a view param (existing order id or nothing to indicate a new order to be created).
When the order detail view is opened an OrderControllerBean is starting a ConversationalScope and depending on the availability of the order id loading or creating a new order entity. This bean is a stateful session bean as well meant to be used as a facade. The bean contains methods for handling order lines, the customer and the payment details as well as saving and deleting an order. These methods use injected EJBs which are designed as stateless session beans as some kind of DAOs to handle the JPA entities order, order line, customer and payment detail.
From the order detail view with customer info, payment info and order line list the user can navigate to the order line detail view adding/editing order lines and to the customer and payment detail view in a similar manner. Those detail views all use the same OrderControllerBean. On the customer, order line and payment detail views there are Ok and Cancel buttons which are not transactional.
On the order detail view there is a Save and Cancel button which should persist all modifications which are done during the conversation.
The question i have now is: is this design suitable and ok?
I am not sure about the following issues:
What happens if the user never use Save or Cancel?
Does everything stay around till the conversion or the session times out?
What does this mean from the transaction perspective?
What does this mean for the managed entities?
What happens if the user leaves his worksplace and comes back later continuing work on the conversation? If the conversation is timed out, how can i gracefully handle this issue?
Stateful beans are a pain and a source of problems in my opinion.
It's better if you handle timeouts at the http session level, rather than givin this responsibility to the Application server (specially since the http session timeout is still relevant you just add another timeout)
You can replace the persitent state provided by the stateful bean with some kind of object caching or if you prefer you can add a sessionid to the database and keep track of your objects states there (it can be special tables to hold temporary objects until saved or discarded for example).
All in all, keep things apart, timeout and temporary objects on the web server side, and use the ejbs for persistence (JPA) and as a facade (stateless beans)
Why do you need to evaluate the either/or situation in creating orders? There should simply be a button that says : New Order that launches a popup form and another, possibly from a datatable row that says "View Order Details".
The design is fine. Just a few tweaks.
You'll want to create and maintain a single session scoped object(call it Visit) in which you store all session related material. I'd advise you stick with the JSF session scoped bean that is dependent on the http session and can be effectively managed by the container. JSF Session Scoped beans are stored as simple objects in the http session and so can be easily manipulated outside the context of JSF. CDI Session Scoped beans however are trickier to handle outside of CDI.
I'll also advise you break up your order creation process into a multi-step process using dynamically loaded page fragments <ui:include/> or the fine primefaces wizard component. With a multi-step creation, all you need to do is gather data along the steps and only commit a transaction when you've all the info you need from all the steps in a DTO. Keep the wizard DTO in the single session object so the container can cleanup in case of a timeout. If the user never saves or cancel or walks away from his desk, the session will die a natural death. And he can come back and continue his transaction if he makes it in time. Not sure what carlos has against stateless session beans but in my experience, they're a nice way of exposing business processes, in that they can expose their functionality in other ways like webservices and message targets (JEE5). Above all, it's very good design to keep as much business processing out of the managed beans as possible and into durable constructs like EJBs and Spring beans etc.
I've been reading up on DDD a little bit, and I am confused how this would fit in when using an ORM like NHibernate.
Right now I have a .NET MVC application with fairly "fat" controllers, and I'm trying to figure out how best to fix that. Moving this business logic into the model layer would be the best way to do this, but I am unsure how one would do that.
My application is set up so that NHibernate's session is managed by an HttpModule (gets session / transaction out of my way), which is used by repositories that return the entity objects (Think S#arp arch... turns out a really duplicated a lot of their functionality in this). These repositories are used by DataServices, which right now are just wrappers around the Repositories (one-to-one mapping between them, e.g. UserDataService takes a UserRepository, or actually a Repository). These DataServices right now only ensure that data annotations decorating the entity classes are checked when saving / updating.
In this way, my entities are really just data objects, but do not contain any real logic. While I could put some things in the entity classes (e.g. an "Approve" method), when that action needs to do something like sending an e-mail, or touching other non-related objects, or, for instance, checking to see if there are any users that have the same e-mail before approving, etc., then the entity would need access to other repositories, etc. Injecting these with an IoC wouldn't work with NHibernate, so you'd have to use a factory pattern I'm assuming to get these. I don't see how you would mock those in tests though.
So the next most logical way to do it, I would think, would be to essentially have a service per controller, and extract all of the work being done in the controller currently into methods in each service. I would think that this is breaking with the DDD idea though, as the logic is now no longer contained in the actual model objects.
The other way of looking at that I guess is that each of those services forms a single model with the data object that it works against (Separation of data storage fields and the logic that operates on it), but I just wanted to see what others are doing to solve the "fat controller" issue with DDD while using an ORM like NHibernate that works by returning populated data objects, and the repository model.
Updated
I guess my problem is how I'm looking at this: NHibernate seems to put business objects (entities) at the bottom of the stack, which repositories then act on. The repositories are used by services which may use multiple repositories and other services (email, file access) to do things. I.e: App > Services > Repositories > Business Objects
The pure DDD approach I'm reading about seems to reflect an Active Record bias, where the CRUD functions exist in the business objects (This I call User.Delete directly instead of Repository.Delete from a service), and the actual business object handles the logic of things that need to be done in this instance (Like emailing the user, and deleting files belonging to the user, etc.). I.e. App > (Services) > Business Objects > Repositories
With NHibernate, it seems I would be better off using the first approach given the way NHibernate functions, and I am looking for confirmation on my logic. Or if I'm just confused, some clarification on how this layered approach is supposed to work. My understanding is that if I have an "Approve" method that updates the User model, persists it, and lets say, emails a few people, that this method should go on the User entity object, but to allow for proper IoC so I can inject the messagingService, I need to do this in my service layer instead of on the User object.
From a "multiple UI" point of view this makes sense, as the logic to do things is taken out of my UI layer (MVC), and put into these services... but I'm essentially just factoring the logic out to another class instead of doing it directly in the controller, and if I am not ever going to have any other UI's involved, then I've just traded a "fat controller" for a "fat service", since the service is essentially going to encapsulate a method per controller action to do it's work.
DDD does not have an Active Record slant. Delete is not a method that should be on an Entity (like User) in DDD.
NHibernate does support a DDD approach very well, because of how completely divorced it remains from your entity classes.
when that action needs to do something
like sending an e-mail, or touching
other non-related objects
One piece of the puzzle it seems you are missing is Domain Events. A domain entity shouldn't send an email directly. It should raise an event in the Domain that some significant event has happened. Implement a class whose purpose is to send the email when the event occurs, and register it to listen for the Domain Event.
or, for instance, checking to see if
there are any users that have the same
e-mail before approving
This should probably be checked before submitting the call to "approve," rather than in the function that does the approving. Push the decision up a level in calling code.
So the next most logical way to do it,
I would think, would be to essentially
have a service per controller
This can work, if it's done with the understanding that the service is an entry point for the client. The service's purpose here is to take in parameters in a DTO from the front end/client and translate that into method calls against an entity in order to perform the desired funcitonality.
The only limitations NHibernate creates for classes is all methods/properties must be virtual and a class must have a default constructor (can be internal or protected). Otherwise, it does not [edit] interfere with object structure and can map to pretty complex models.
The short answer to you question is yes, in fact, I find NHibernate enhances DDD - you can focus on developing (and altering) your domain model with a code first approach, then easily retro-fit persistence later using NHibernate.
As you build out your domain model following DDD, I would expect that much of the business logic that's found you way into you MVC controllers should probably reside in your domain objects. In my first attempt at using ASP.NET MVC I quickly found myself in the same position as yourself - fat controllers and an anemic domain model.
To avoid this, I'm now following the approach of keeping a rich domain model that implements the business logic and using MVC's model as essentially simple data objects used by my views. This simplifies my controllers - they interact with my domain model and provide simple data objects (from the MVC model) to the views.
Updated
The pure DDD approach I'm reading about seems to reflect an Active Record bias...
To me the active record pattern means entities are aware of their persistance mechanism and an entity maps directly to a database table record. This is one way of using NHibernate e.g. see Castle Active Record, however, I find this pollutes domain enitities with knowledge of their persistence mechanism. Instead, typically, I'll have a repository per aggregate root in my domain model which implements an abstract repository. The abstract repository provides basic CRUD methods such as:
public IList<TEntity> GetAll()
public TEntity GetById(int id)
public void SaveOrUpdate(TEntity entity)
public void Delete(TEntity entity)
.. which my concrete repositories can supplement/extend.
See this post on The NHibernate FAQ which I've based a lot of my stuff on. Also remember, NHibernate (depending on how you set up your mappings) will allow you to de-persist a complete object graph, i.e. your aggregate root plus all the objects hanging off it and once you've finished working with it, can cascade saves through you entire object graph, this certainly isn't active record.
...since the service is essentially going to encapsulate a method per controller action to do it's work...
I still think you should consider what functionality that you currently have in your controllers should, more logically, be implemented within your domain objects. e.g. in your approval example, I think it would be sensible for an entity to expose an approve method which does whatever it needs to do to within the entity and if, as in your example, needs to send emails, delegate this to a service. Services should be reserved for cross-cutting concerns. Then, once you've finished working with your domain objects, pass them back to your repository to persist changes.
A couple of books I've found useful on these topics are:
Domain-Driven Design by Eric Evans
Applying Domain-Driven Design and Patterns by Jimmy Nilsson
I want to implement event management in my application and i wanna know what may be the best practice to achieve this goal. Event management in my case is to maintain a log of every insert/update/delete operation in my application.
It sounds like you are refering to a database event, in that case i would use triggers on the db and not bother with any ASP.Net implementation.
What data access layer are you using? If you're using LINQ to SQL or Entity Framework you could hook into events in their contexts to track these operations. Or, if you have a service tier through which these operations all flow, you could raise events there.
Specifically, since you are using LINQ to SQL, then you can implement the partial methods InsertEntity, UpdateEntity, and DeleteEntity (where Entity is the name of each of your entities) on your strongly-typed DataContext. These hooks should be the exact place to perform your logging or other event processing.
Use Change Data Capture http://www.mssqltips.com/tip.asp?tip=1474
I agree with the answer that it can be done in the DB layer by using triggers. If you don't want to put it in the db layer, you can create an action filter for all of your actions (add/update/delete) - which writes to the log.