Here is the situation, in order to support our legacy system, we need to insert to a table whenever a user logs in. This is basically an CRUD operation, so it doesn't really make sense to create repository/entity/command/event for this since this doesn't tie to any business rules at all. The only benefit to create a CQRS command is that this database write can happen asynchronously under that model. Which is a better route to take?
Use CQRS, and then call a stored proc.
when handling that command?
Just call database directly in the controller (I am using asp.net mvc)
If you are using (and persisting) events for possible playback, then it makes sense to do the writing to a legacy DB as part of an event handler (think "gateway"). If you need to replay this event in the future you can swap in a fake handler that doesn't reinsert the record.
Your controller should really only be a translation layer between and HTTP request and a command for your domain. Writing to a DB (even legacy, non-domain access) doesn't really make sense there, IMHO. Putting the logic in an event handler makes the interaction very explicit.
Related
We are considering breeze js to build enterprise applications.
The awesomeness of breeze is that we can execute queries right from the client browser. This allows to constructs dynamic queries based on the users input without loading unnecessary data. I have found that using Breeze we can create business logic that reduces data traveling/transferring by 1/10 or even more when using a lazy loading strategy. using queries like these
Hooray breeze!!!
But what about Business Logic security,
For example, We could have a repository in which we could conceal, hide and obscure our business logic; and then use MVC Web API controllers to just make calls to those repository C# classes. so Breeze JavaScript talks to the WebAPi controller and the WebApi controller talks to the C# repository. The Controllers will always be kept very simple and easy to read, but the Repository may end up having lots of business logic for the company using the application. So if a hacker uses, for example, the Google Chrome developer's console to inspect the JavaScript code, all he/she will see are things like GetCustomers(), GetProductsForThisId(54). There is not much information that can be seen (or stolen) there. Because 90% of the Business Logic will live on the C# repository on the server .
How is breeze.js handling that ?
If we start moving the queries and business logic "from the controller's C# to the breeze JavaScript", we have to consider that our system is membership based. I think the more queries we expose to the client in JavaScript, the more vulnerable our software becomes, and the more we tell hackers how to hack our website and possibly steal information.
Security is a vital concern. It is wise to think carefully about the data and logic exposed on the client. How can we refine these sentiments into a concrete question suitable for an SO answer?
Nothing about Breeze should cause you to expose business logic to the JavaScript client. You can (and should) lock such logic safely inside your repositories and/or controller methods.
But I struggle to understand how client queries themselves are the kinds of business logic that need protecting. Where's the danger in a query for a customer whose name begins with 'A'?
You may rightly worry about a query for customers with net worth > $100,000. But the fault is not in the query. The fault would be in exposing such customer information to unauthorized users by any means, whether through a Breeze where clause appended to a query or a call to a service named GetCustomers().
The place to block unauthorized access to customers is on the server and you can do that as easily inside a Breeze controller action method returning IQueryable as you can in your GetCustomer() method. The burden falls on you in either case to impose the necessary security constraints on your controller and within the methods that you expose.
You write the controller. You write the repositories. You have access to the user's permissions. You are in complete control with an uncompromised ability to expose as much or as little as you wish.
FWIW, your Breeze EntityManager can call service methods that do not return IQueryable<Customer>. It can call Web Api controller methods such as IEnumerable<Customer> GetCustomers() or Product GetProductForId(int id). In my opinion you will lose the flexibility of Breeze's query facilities without gaining any security. But that's just my opinion. Breeze will support your choice, whatever it may be.
I'd be happy to try to answer a more specific "how to" question.
would like to add that you can restrict users that are not authorized from quering by using the attributes in webapi if you get 401 code back from the server just popup a login screen and redo the work needed after the user is logged in
so a user may try to get data about an order but he won't get it unless he is authorized to do so
You can to a lot of stuff using breeze.js
First of all check my answer regarding security here
How to handle authorization with Breeze JS?
Also although breeze.js can be used like a normal ORM on the client (which can be extremely helpful at times), you should keep your business logic in web api controllers and expose only the necessary stuff using OData queries.
If you need any data manipulation logic, then you should do it on the server using a specific method for that.
Only UI logic should be present on the client, also consider that there are several performance implications if you start performing multiple queries directly from the client. Either expand the entity graph to load more results or use more specialized methods that return object. Breeze will introspect the results and consume the entities happily without implications.
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
problem:
On first full page request, my controller invokes an applicationServices Layer (Web Service Proxy to my business tier) in order to populate a collection of current services that is stored in my own controller base class property. This is then to be displayed within a view.
Everything within the context of that controller has access to this "Services Collection". Now when i make further calls to the same action method via an AJAX Call, i obviously hitt a different instance of that controller meaning my services collection is empty.
So other than re-getting the whole collection again, where would i store this collection so it gets persisted between ajax requests? Should i persist it as a seperate DomainModel Object, Session object?....as ViewData is not working for me obv. Excuse my MVC ignorance :)
Any help would be greatly appreciated :)
The web is essentially stateless and MVC helps you to go down to the metal, that is, MVC does not try to make something stateful that isn't, which is mostly the path of ye olde ASP: Each request is a request of it's own and it shouldn't know anything about any other request that has been performed in the past.
I feel it is easiest to go down exactly that route, because it it tends to stay clean, fast and helps you in adhering to best practices such as separation of concerns.
AJAX takes this a step further: The idea of AJAX is that a simple 'delete' operation can be implemented as such, i.e. you only need to authorize and perform one very small query on the persistence layer. That's it. You don't even need to pass a modified page back to the user. A simple machine-readable success/error indication via JSON is sufficient.
If you start to pull lots of services around for small AJAX requests, you really lose most of what it's good for.
I'd also suggest you don't store a bunch of services in a base controller. Chances are that for most requests, you will only need a small subset of these. It's best practices to retrieve only those service you absolutely positively need.
I have an MVC app I'm writing. There will be the need for multiple instances of the same page to be open, each accessing different records from a database, these record objects will also need to be passed through a flow of pages, before finally being updated.
What's the best, and most correct, way of acheiving this - should/can I create a custom model binder that links to an object via it's unique ID and then create each record-object in the session, updating them as I go through each one's page flow and then finally calling the update method? Or is there a better way of dealing with this?
Cheers
MH
Technically, that would be possible, but I don't think it is advisable. When you look at the signature of IModelBinder, you will have to jump through some hoops related to the ControllerContext if you want to be able to access the rest of your application's context (such as how to dehydrate objects based on IDs).
It's possible, but so clunky that you should consider whether it's the right approach. In my opinion, a ModelBinder's responsibility is to map HTTP request data to strongly typed objects. Nothing more and nothing less - it is strictly a mapper, and trying to make it do more would be breaking the Single Responsibility Principle.
It sounds to me like you need an Application Controller - basically, a class that orchestrates the Views and the state of the underlying Model. You can read more about the Application Controller design pattern in Patterns of Enterprise Application Architecture.
Since a web application is inherently stateless, you will need a place to store the intermediate state of the application. Whether you use sessions or a custom durable store to do that depends on the application's requirements and the general complexity of the intermediate data.
I'm currently working on an ASP.NET MVC project using NHibernate and I need to keep track of changes on some entities in order to be able to make some reports and queries over the data. For this reason I wanted to have the data in a table, but I'm trying to decide where to "hook" the auditing code.
On the NHibernate layer:
PRO: Powerful event system to track any change
PRO: Nothing can be changed in the application without notice (unless someone uses raw SQL...)
CON: As I have a generic repository... then I have to filter out the useful entities (I don't need to track everything).
CON: I don't have easy access to the controller and the action so I can only track basic operations (update, delete...). I can get the HttpContext at least to get some info.
On an Action Filter at Controller level:
PRO: Full information on the request and web application status. This way I can distinguish an "edit" from a "status change" and be more descriptive in the audit information.
CON: Someone can forget a filter and an important action can be taken without notice which is a big con.
Any clue?
Update: See how to Create an Audit Log using NHibernate Events.
I think doing this at the repository level is a much better fit. Mostly because you may, in the future, decide to add some method of access to your repository which does not go through MVC (e.g., a WCF interface to the data).
So the question becomes, how do you address the cons you've listed about doing it on the NHibernate layer?
Filtering out the useful entities is simple enough. I would probably do this via a custom attribute on the entity type. You can tag the entities you want to track, or the ones you don't; whichever is easier.
Figuring out what the controller really intended is harder. I'm going to dispute that you can "get the HttpContext"; I don't think it is a good idea to do this in a repository, because the separation of concerns. The repository should not be dependent on the web. One method would be to create custom methods on the repository for actions you'd like to track differently; this is especially attractive if there are other aspects of these edits which behave differently, such as different security. Another method is to examine the changes by comparing the old and new versions of the objects and derive the actual nature of the change. A third method is to make no attempt to derive the nature of the change, but just store the before and after versions in the log so that the person who reads the log can figure it out for themselves.
I'd rather put it in the data (NHibernate in your case) layer. Putting it in the controller and asking other people (or yourself, in the future) to implement controllers accordingly conflicts with object-oriented design principles.
I do this with NHibernate. Objects that require auditing implement an IAudtable interface and I use an Interceptor do the auditing on any object that implements IAuditable by intercepting OnFlushDirty, OnDelete, and OnSave.