Link to home
Start Free TrialLog in
Avatar of kkamm
kkammFlag for United States of America

asked on

Passing results of operations in a Data Access Layer back to calling layers? Best practice?

i have an application where I am trying to adhere to  n-Tier architecture principles. I want to keep a fairly strict pathway to my data access layer for both input and output. Input is passed through typed parameters passed from the calling routines in my business logic layer, but I have a variety of possible return values that need to get passed back to the caller. Some routines only return a boolean indicating the success of an operation, whereas others return data objects,etc.

What I would like to do is create a generic return object that all my DAL routines could make use of, and give calling routines a consistent interface for the return values. I would like this object to contain the results of each DAL operation. If an exception occurs, I want to be able to pass the details of the exception back to the caller. If a data row or a data table needs to be passed back to the caller, I would like to be able to do it through this generic object.

My tentative idea is to create a class that would contain a boolean property indicating the success of the DAL operation, a custom exception object, and a generic return object for any data that needs to be passed back to the caller. I could then load this return object with the appropriate information and return it to the caller.

My question is whether or not this is considered a 'bast practice' in the n-Tier realm? In the past, I have just handled the results of various routines locally, but with a layered architecture that approach seems to yield hard-to-maintain spaghetti code.
ASKER CERTIFIED SOLUTION
Avatar of abel
abel
Flag of Netherlands image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of kkamm

ASKER

Abel,

Thanks for the info.

I am currently using .NET typed datasets and I am doing various per-table CRUD operations through that.  My DAL works with the dataset and the BLL works with the DAL to create and manipulate various custom business objects to present to a WPF front-end. My application will probably not be web-based.

Does NHibernate have a significant learning curve? I am reticent to spend more development time on learning yet another tool.
> Does NHibernate have a significant learning curve?

It depends on where you are coming from. For somebody with ample years of experience, of which quite some in enterprise development, it shouldn't be too hard to grasp the sometimes rather abstract concepts. But these are concepts that have stood the test of time and are now used in many large and very large organizations.

The problem is usually: getting started and at the same time building up an enterprise ready approach to your data. Which means, no time to learn it the hard way. Like with many projects, your best bet is to hire a professional who can set it up and then explain it to you and who can be available when trouble strikes later (I am available! lol).

Once a system like described above is setup up, it is amazingly fast and versatile, quite easy to maintain but above all, easy to use.

I don't know how small or wide your project is going to be. But considering the subject and the area where you posted the question, I assume that it is a bit more than the most basic example. If you do want a professional review of your situation, I can move and act fast and have a possible large team of experts to help.

But I'll also be around the EE area most of the time and will be happy to consult you with the steps to take on hibernate through the Q/A system of EE.
Avatar of kkamm

ASKER

The application I am working on is not enterprise-grade, but it will be used in a medical data context, so I am rather concerned with correctness of data,etc. The database schema is relatively straight-forward. Most operations are single table, with an occasional parent-child relation.

Right now, a key concern would be the data representations available through the BLL layer, as my WPF UI is driven by collections from the BLL that represent queried data from the DAL. Does NHibernate allow you to specify custom types for holding memory-resident data? Specifically, my primary collection type is derived from an Observable Collection which I then use to bind to my UI controls. If I could use NHibernate to generate an infrastructure that would provide me with a UI-to-database pipeline, then it may be worth the learning curve.
Yes, you can use any custom types you like. The end result is usually, that you have some place where you define what columns / fields go into what properties (getters/setters). This process can be automated. If you want them inside currently existing collections, or make use of existing base types or interfaces, that shouldn't be too much of a problem.

It sure is worth the learning curve! Once you get the hang of it, your next DB project will be setup in no-time, with much more data integrity security, higher performance and simply more possibilities because of a less complex UI layer.
Avatar of kkamm

ASKER

You mentioned the possibility of using outside consultancy as a means to expedite this process. Are there firms that specialize in NHibernate development? What is a typical rate for a contract job of this type?

The reason I ask is that I am weighing the cost of development in-house vs. a contract job for the DAL. This project is currently an in-house project, but is being designed with an intent to market it eventually.  The work I am currently doing seems to be "re-inventing the wheel" at the DAL level, and I would rather be attending to the functionality of the program according to our user requirements.

If NHibernate is an industry standard for data access, and we want to be able to market our system, then it may well be worth the benefits of hiring someone to assist us with this.


Well, you're asking the wrong guy, because with such a request I can only start promoting myself ;-).

All larger projects I worked with in the last 4-5 years involved Hibernate (java projects) and NHibernate. The projects I did this for ranged from 25K to 55M, but I was mainly active in the mid-section of the market (around 200K). Of course, NHibernate was only a part of those budgets (Euro).

Anyway, I can offer myself, I can offer you other companies and I can offer you an offshore team with (N)Hibernate knowledge. Pricing and other acquisitional like talk I'd rather do over the telephone or by mail. You can find both in my profile (EE guidelines allow it in profile, not in discussion threads).

In all humbleness (ahum), I can help you set it up quickly and stable/reliable, with the necessary hand-over documentation and post-delivery support, and I can travel if necessary.

-- Abel --
Avatar of kkamm

ASKER

Abel,

I will have to do some more research on NHibernate to see if it fits our purposes, but I may need to get more information from you along the way.

With regards to the original question-what have you encountered as far as exception handling and return values/objects coming from a DAL layer? Is it common practice to wrap this sort of content in a custom object and pass it back to a calling layer?
I'll be around for that ;)

Yes, I would pass it back to the calling layer. It is commonly considered good practice not to hide exceptions, unless you can handle them. Some exceptions might or might not be handled by the DAL, but the rest should just be propagated forward.

My own preference, however, dictates that the DAL should expose its own layer of custom exceptions. The InnerException should be set to the NHibernate Exception (or other style of DAL layer related exception). The reason for this wrapping is simple: you do not want the calling layer to need to have knowledge or information about NHibernate. You want it to deal with the abstraction layer.
Avatar of kkamm

ASKER

If I throw a custom exception in the DAL layer, is it considered best practice to catch it in the calling layer or should I keep all layer-specific error handling within the layer and make the exception details available via a custom object that holds the details of the exception?

Ah, now your touching at a much debated subject. With my method described above (with custom exceptions, I do mean exceptions), I would choose the exceptions way, which is what they're there for.

But, slightly depending on your demands, it might suit you better to do an after-the-fact check by allowing an error object around, so that you do not need try/catch. But this is usually a trap and will bring you in the long run into the same trouble as it brought Microsoft old-style coding with GetLastError. I would advice against it.

You can also blend the two methods. Use exceptions AND use an error handler event. You can make it optional that the exceptions are thrown. But this is closely the same as creating a global exception handler which you would use for logging the errors anyway (log4net works with NHibernate).
Avatar of kkamm

ASKER

Some potential and knowable errors, like a network interface being unavailable, I can check for before even trying to instantiate a connection object. This can be taken care of explicitly in the DAL, as that is the only layer given access to the server.

My Try-Catch block for a DAL CRUD operation should only be entered after certain knowable error conditions are found to be absent. The unknowable stuff, however, I could catch as a general exception and rethrow as a custom exception for the BLL to catch. The BLL could, in turn, throw an exception that could be caught at the UI level.

The problem with a general handler would seem to be that I could not do localized cleanup if an operation failed. Right now, I have an INSERT methodology where I can't commit any changes to my UI or BLL collections until it is confirmed that a row has been created in the database and an identity value has been returned. If I encounter an error in creating that row, then I simply abort the corresponding CRUD operations for my BLL and UI, but I need to be able to register the error at each layer.

Does it make sense to define custom exceptions for each layer and catch them at the next layer up? It seems there would still be logical separation of layers that need not communicate with one another.
Avatar of kkamm

ASKER

Abel,

I was experimenting with custom exceptions and I wanted to pass this by you before finishing up this thread.

I attached a very basic code sample of something I am trying. The gist of it is that if an error occurs locally then a new custom exception iis thrown so that the orginal callier can handle it specifically. If an exception is simply "passing through" from a deeper call then the specific exception is rethrown. It seems to work like channels for each layer, ending at the base layer, where no further exceptions are thrown.







Private Sub BaseCall()
	Try
	CallOne
	Catch CallOneEx As CallOneException
        Catch CallTwoEx As CallTwoException
	Catch Ex As Exception
        Finally
        End Try
    End Sub
 
Private Sub CallOne()
	Try
	CallTwo
        Catch CallTwoEx As CallTwoException
	Throw
        Catch Ex As Exception
        Throw New CallOneException       
	Finally
        End Try
    End Sub 
 
Private Sub CallTwo()
        Try
        Catch ex As Exception
        Throw New CallTwo Exception
        Finally
        End Try
    End Sub

Open in new window

Avatar of kkamm

ASKER

Abel,

I posted a spinoff question for exceptions:

https://www.experts-exchange.com/questions/24365509/Exception-handling-in-an-n-Tier-application-best-practices.html

Thanks for all your help.
tx for the grade, kkamm, I believe I didn't get your last two follow-ups through my mail. That happens sometimes. Looks like you have quite some activity in the other question now, so at least you were not entirely abandoned :)