I need to be able to validate some business rules on entities before any modification to DB is performed (Create, Update, Delete), and throw exception and rollback if these rules fail. I am building a framework and I want to do that always, despite whether user use my class to modify entities or directly NHibernate Session. I also need to be able to customize these business rules, depending on configuration file.
I've tried to inherit DefaultSaveOrUpdateEventListener, overriding PerformSaveOrUpdate, PerformUpdate, PerformSaveOrReplicate, PerformSave, OnSaveOrUpdate and DefaultSaveEventListener with overriding PerformSaveOrUpdate, PerformSave, PerformSaveOrReplicate, PerformUpdate, OnSaveOrUpdate. I just put Debug.WriteLine, and called the base implementation. I didn't find any good and detailed description of those, so I tried everything that seems like what I need.
And I have initialized them like this:
configuration.EventListeners.SaveOrUpdateEventListeners[0] = new SaveOrUpdatePermissionListener(_mappingContext);
configuration.EventListeners.SaveEventListeners[0] = new SavePermissionListener(_mappingContext);
But looks like this does not always work. If I modify objects in the object tree, for some reason these methods catch all objects except of the root object.
What I did wrong? Maybe there are better ways of doing what I want to do?
Was able to do that, by inheriting IPreUpdateEventListener, IPreDeleteEventListener, IPreInsertEventListener interfaces instead of DefaultSaveOrUpdateEventListener and DefaultSaveEventListener.
Still, if anybody has a better idea of achieving the task, I'm eager to listen.
Related
I am new to Razor Pages and looking for the best way to solve my problem.
Say I have an IndexModel class, that has some properties that rely on a DB context that is injected via the Constructer, such as a drop down list of Membership Levels, that comes directly from a table...
My question is what is the best way to handle populating this drop down list that I have for ALL requests that results in the same page being reloaded / returned. I know that I can put logic in OnGet to set up the list, the problem arises if say in OnPost, ModelState.IsValid is false, and so the page is returned with Page(). If I don't explicitly reinitialize the select list in OnPost, then I get a null reference exception, which is fair enough. Rewriting the code in the OnPost method goes against DRY principles, so I looked to writing a ConfirgureProperties() method in the class when needed.
Then by testing, I found that I can just set up a constructer that will take care of populating properties for me whenever they are needed, and I don't have to call anything else. Even when DI is involved, the injection is resolved at the top of the constructer, then I can use the context to do what I need for the other properties later in the constructer. I have seen no examples of this anywhere online, I only ever see people using constructers in page models that handle DI EXCLUSIVELY.
Is there a reason I SHOULD NOT be doing this, like bad coding practice or something, or is it ok for me to use page model constructers in this way?
Thanks
You only need to make the database call to repopulate the options in OnPost if ModelState is invalid. Chances are, if you have set up your validation correctly, that 99% of the time validation errors will be caught on the client and you won't need to repopulate the options.
Obtaining data from a database is costly, and you should only do it when necessary. So using the constructor approach contravenes this principal.
It's not like you are saving a lot of code either. Your ConfigureProperties method will only be called in two places in the PageModel.
I'm starting to work with MongoDB using official c# driver. The problem is that I can't find a way to make bsonseriazer use fields (not properties) for setting the deserialized data and at the same time being able to use LINQ Api.
When mapping my class, I use BsonClassMap.FieldMap(). But this doesn't allow to use LINQ, since public properties remain unmapped.
Is there a way in BsonSerializer to do mappings based on properties, but at the same time specify that these should be set directly via their backing fields?
The reason I want to use fields for deserialization, is to omit custom validation rules that might be checked in setter.
I think you should keep those validation rules even when the data comes from your own database. It's much cleaner, less bug-prone and is more secure.
You can create your own BsonSerializers (or extend an existing one) that act which ever way you want. I've made several of those and it's really simple.
You can have a bool _isInitialized = false; in your DTOs that you set to true right after you get items from the MongoDB driver and forgo the validation rules until it is set.
I don't see another way to "split" the mapping to both the properties (for Linq) and data members (for serialization) and I recommend the first option.
Back story:
So I've been stuck on an architecture problem for the past couple of nights on a refactor I've been toying with. Nothing important, but it's been bothering me. It's actually an exercise in DRY, and an attempt to take it to such an extreme as the DAL architecture is completely DRY. It's a completely philosophical/theoretical exercise.
The code is based in part on one of #JohnMacIntyre's refactorings which I recently convinced him to blog about at http://whileicompile.wordpress.com/2010/08/24/my-clean-code-experience-no-1/. I've modified the code slightly, as I tend to, in order to take the code one level further - usually, just to see what extra mileage I can get out of a concept... anyway, my reasons are largely irrelevant.
Part of my data access layer is based on the following architecture:
abstract public class AppCommandBase : IDisposable { }
This contains basic stuff, like creation of a command object and cleanup after the AppCommand is disposed of. All of my command base objects derive from this.
abstract public class ReadCommandBase<T, ResultT> : AppCommandBase
This contains basic stuff that affects all read-commands - specifically in this case, reading data from tables and views. No editing, no updating, no saving.
abstract public class ReadItemCommandBase<T, FilterT> : ReadCommandBase<T, T> { }
This contains some more basic generic stuff - like definition of methods that will be required to read a single item from a table in the database, where the table name, key field name and field list names are defined as required abstract properties (to be defined by the derived class.
public class MyTableReadItemCommand : ReadItemCommandBase<MyTableClass, Int?> { }
This contains specific properties that define my table name, the list of fields from the table or view, the name of the key field, a method to parse the data out of the IDataReader row into my business object and a method that initiates the whole process.
Now, I also have this structure for my ReadList...
abstract public ReadListCommandBase<T> : ReadCommandBase<T, IEnumerable<T>> { }
public class MyTableReadListCommand : ReadListCommandBase<MyTableClass> { }
The difference being that the List classes contain properties that pertain to list generation (i.e. PageStart, PageSize, Sort and returns an IEnumerable) vs. return of a single DataObject (which just requires a filter that identifies a unique record).
Problem:
I'm hating that I've got a bunch of properties in my MyTableReadListCommand class that are identical in my MyTableReadItemCommand class. I've thought about moving them to a helper class, but while that may centralize the member contents in one place, I'll still have identical members in each of the classes, that instead point to the helper class, which I still dislike.
My first thought was dual inheritance would solve this nicely, even though I agree that dual inheritance is usually a code smell - but it would solve this issue very elegantly. So, given that .NET doesn't support dual inheritance, where do I go from here?
Perhaps a different refactor would be more suitable... but I'm having trouble wrapping my head around how to sidestep this problem.
If anyone needs a full code base to see what I'm harping on about, I've got a prototype solution on my DropBox at http://dl.dropbox.com/u/3029830/Prototypes/Prototype%20-%20DAL%20Refactor.zip. The code in question is in the DataAccessLayer project.
P.S. This isn't part of an ongoing active project, it's more a refactor puzzle for my own amusement.
Thanks in advance folks, I appreciate it.
Separate the result processing from the data retrieval. Your inheritance hierarchy is already more than deep enough at ReadCommandBase.
Define an interface IDatabaseResultParser. Implement ItemDatabaseResultParser and ListDatabaseResultParser, both with a constructor parameter of type ReadCommandBase ( and maybe convert that to an interface too ).
When you call IDatabaseResultParser.Value() it executes the command, parses the results and returns a result of type T.
Your commands focus on retrieving the data from the database and returning them as tuples of some description ( actual Tuples or and array of arrays etc etc ), your parser focuses on converting the tuples into objects of whatever type you need. See NHibernates IResultTransformer for an idea of how this can work (and it's probably a better name than IDatabaseResultParser too).
Favor composition over inheritance.
Having looked at the sample I'll go even further...
Throw away AppCommandBase - it adds no value to your inheritance hierarchy as all it does is check that the connection is not null and open and creates a command.
Separate query building from query execution and result parsing - now you can greatly simplify the query execution implementation as it is either a read operation that returns an enumeration of tuples or a write operation that returns the number of rows affected.
Your query builder could all be wrapped up in one class to include paging / sorting / filtering, however it may be easier to build some form of limited structure around these so you can separate paging and sorting and filtering. If I was doing this I wouldn't bother building the queries, I would simply write the sql inside an object that allowed me to pass in some parameters ( effectively stored procedures in c# ).
So now you have IDatabaseQuery / IDatabaseCommand / IResultTransformer and almost no inheritance =)
I think the short answer is that, in a system where multiple inheritance has been outlawed "for your protection", strategy/delegation is the direct substitute. Yes, you still end up with some parallel structure, such as the property for the delegate object. But it is minimized as much as possible within the confines of the language.
But lets step back from the simple answer and take a wide view....
Another big alternative is to refactor the larger design structure such that you inherently avoid this situation where a given class consists of the composite of behaviors of multiple "sibling" or "cousin" classes above it in the inheritance tree. To put it more concisely, refactor to an inheritance chain rather than an inheritance tree. This is easier said than done. It usually requires abstracting very different pieces of functionality.
The challenge you'll have in taking this tack that I'm recommending is that you've already made a concession in your design: You're optimizing for different SQL in the "item" and "list" cases. Preserving this as is will get in your way no matter what, because you've given them equal billing, so they must by necessity be siblings. So I would say that your first step in trying to get out of this "local maximum" of design elegance would be to roll back that optimization and treat the single item as what it truly is: a special case of a list, with just one element. You can always try to re-introduce an optimization for single items again later. But wait till you've addressed the elegance issue that is vexing you at the moment.
But you have to acknowledge that any optimization for anything other than the elegance of your C# code is going to put a roadblock in the way of design elegance for the C# code. This trade-off, just like the "memory-space" conjugate of algorithm design, is fundamental to the very nature of programming.
As is mentioned by Kirk, this is the delegation pattern. When I do this, I usually construct an interface that is implemented by the delegator and the delegated class. This reduces the perceived code smell, at least for me.
I think the simple answer is... Since .NET doesn't support Multiple Inheritence, there is always going to be some repetition when creating objects of a similar type. .NET simply does not give you the tools to re-use some classes in a way that would facilitate perfect DRY.
The not-so-simple answer is that you could use code generation tools, instrumentation, code dom, and other techniques to inject the objects you want into the classes you want. It still creates duplication in memory, but it would simplify the source code (at the cost of added complexity in your code injection framework).
This may seem unsatisfying like the other solutions, however if you think about it, that's really what languages that support MI are doing behind the scenes, hooking up delegation systems that you can't see in source code.
The question comes down to, how much effort are you willing to put into making your source code simple. Think about that, it's rather profound.
I haven't looked deeply at your scenario, but I have some thoughs on the dual-hierarchy problem in C#. To share code in a dual-hierarchy, we need a different construct in the language: either a mixin, a trait (pdf) (C# research -pdf) or a role (as in perl 6). C# makes it very easy to share code with inheritance (which is not the right operator for code-reuse), and very laborious to share code via composition (you know, you have to write all that delegation code by hand).
There are ways to get a kind of mixin in C#, but it's not ideal.
The Oxygene (download) language (an Object Pascal for .NET) also has an interesting feature for interface delegation that can be used to create all that delegating code for you.
I'm not positive I have the right architecture for this problem. Let's say I have a Person object that has 1 or more Attribute objects associated with it. For the interface, I have a list of Person objects, a Person view, and another control with tab pages that represent each Attribute object associated with that person. How would an MVC architecture behind that be constructed?
Currently, I have a single 'model' for a Person that has a list of Attribute models. I have a controller for the view, and then I was going to make a controller for the AttributeView that would have sub-controllers for each Attribute attached to each Attribute model in the Person model... I think I can handle all the appropriate interactions with that architecture, but I'm not sure that it's the best implementation. Does that sound reasonable, or is there a better way to tackle this?
Thanks!
If it was me, I wouldn't bother having the main controller know about the sub-controllers for the attributes; I'd make that connection at the view level instead. So you'd have a PersonView that knows how to construct AttributeViews (passing in AttributeModels to them) -- or has a handle to a factory that knows that -- and the AttributeViews would know how to construct AttributeControllers.
Depends a bit on what you're trying to do, though. Like, do you need to be able to commit / roll back changes to an AttributeModel without actually committing those changes to the Person? Do you need to roll back changes to the Person as a whole? If the user selects a different Person in the list, do you need to do some validation before committing the changes, or to prompt them to save changes before switching Persons? Stuff like that is where the mess is likely to be.
I am currently playing around with the Asp.Net mvc framework and loving it compared to the classic asp.net way. One thing I am mooting is whether or not it is acceptable for a View to cause (indirectly) access to the database?
For example, I am using the controller to populate a custom data class with all the information I think the View needs to go about doing its job, however as I am passing objects to the view it also can cause database reads.
A quick pseudo example.
public interface IProduct
{
/* Some Members */
/* Some Methods */
decimal GetDiscount();
}
public class Product : IProduct
{
public decimal GetDiscount(){ ... /* causes database access */ }
}
If the View has access to the Product class (it gets passed an IProduct object), it can call GetDiscount() and cause database access.
I am thinking of ways to prevent this. Currently I am only coming up with multiple interface inheritance for the Product class. Instead of implementing just IProduct it would now implement IProduct and IProductView. IProductView would list the members of the class, IProduct would contain the method calls which could cause database access.
The 'View' will only know about the IProductView interface onto the class and be unable to call methods which cause data access.
I have other vague thoughts about 'locking' an object before it is passed to the view, but I can foresee huge scope for side effects with such a method.
So, My questions:
Are there any best practices regarding this issue?
How do other people using MVC stop the View being naughty and doing more to objects than they should?
Your view isn't really causing data access. The view is simply calling the GetDiscount() method in a model interface. It's the model which is causing data access. Indeed, you could create another implementation of IProduct which wouldn't cause data access, yet there would be no change to the view.
Model objects that do lazy loading invariably cause data access when the view tries to extract data for display.
Whether it's OK is down to personal taste and preference.
However, unless you've got a good reason for lazy loading, I'd prefer to load the data into the model object and then pass that "ready-baked" for the view to display.
One thing I am mooting is whether or not it is acceptable for a View to cause (indirectly) access to the database?
I've often asked the same question. So many things we access on the Model in Stack Overflow Views can cause implicit database access. It's almost unavoidable. Would love to hear others' thoughts on this.
If you keep your domain objects "persistent ignorant", then you don't have this problem. That is, instead of having getDiscount inside your Product class, why not just have a simple property called Discount? This would then be set by your ORM when loading the instance of the Product class from the database.
The model should not have methods ("actions") that consist of data access. That's the DAL's concern. YOu could have a discount percent property stored in the product class and have the GetDiscount method return a simple calculation such as Price * (100 - discountPercent) or something like this.
I disconnect my business entities (Product in your example) from data access. That's the repository (in my case) 's concern.
I've built a site in MonoRail before that sometimes has methods that trigger data access from the view. I try to avoid it because when it fails, it can fail in unusual and unfixable ways (I can't really try/catch in an NVelocity template, for example). It's totally not the end of the world--I wrote well-abstracted PHP sites for years that accessed the database from the view and they still work well enough because most of the time if something blows up, you're just redirecting to a "Something didn't work"-type error page anyway.
But yeah, I try to avoid it. In a larger sense, my domain model usually doesn't trickle all the way down into the view. Instead, the view is rendering Document objects that are unashamedly just strongly-typed data dumps, with everything pre-formatted, whipped, crushed, and puree'd to the point where the view just has to spit out some strings with some loops and if/else's, transform the number "4" into 4 star images, etc. This document is usually returned by a Web service that sits in front of the beautiful domain model, or it's just a simple struct that is constructed in the controller and passed along as part of the ViewData. If a domain object is used directly, then it usually doesn't do anything to explicitly trigger data access; that's handled by a collection-like repository that the view doesn't have access to and the domain objects usually don't have access to, either.
But you don't have to do it that way. You could just be discplined enough to just not call those methods that touch the database from the view.