I have a question regarding n-layer architecture. I thought long and hard before asking this question as there's a lot of similar questions here already... however, after literally a day and a half looking at it and reading these other answers I'm still unsure. The variety of seemingly similar terminology and different approaches has me confused.
If I had a BLL and a DAL in different class libraries, one way to communicate between the BLL and DAL would be to utilise an interface, kind of like a DTO defined in another separate DLL that was referenced by both BLL and DAL. My domain model entities in the BLL would implement this interface and so would any ORM generated objects in the DAL. To save my business entities I could then pass them to the DAL which would accept them fine because they implement the shared interface. I could also pass objects back to the BLL that implement this interface. This seems reasonable as both BLL and DAL then only need to be aware of the basic interface, not each others concrete implementation.
My question is what is what's the best method for creating the object on the other side? For example if I had a Person object in the BLL that implemented IPerson, and a PersonDataObject or whatever in the DLL that also implements IPerson, I pass Person to a method in the DAL which takes a parameter of IPerson, then in the DAL I'd have to reconstruct a PersonDataObject to persist. Is this even the best method?
Sorry I probably haven't explained this all too well as I'm pretty confused. A best practice for dummies answer would be much appreciated.
While following the n-tier architecture, it is very common to share the data objects between BL and DAL. Sometimes, the same data object can be used in the UI layer as well.
Usually I have a Data Model (or data objects or domain model, whatever you name it) assembly that houses all model objects as interfaces. Taking your people example, I will create an IPeople interface in model assembly. DAL will return an instance of IPeople to BL. BL will consume this instance and if required pass this on to the UI layer after applying business logic.
Generally speaking, objects in the BLL will consume the interfaces - not implement them:
Taking a "Person" as an example: think about the different data operations associated with a person (Getting all the data for a single person, a collection of shallow data for many persons, CRUD operations, searching, etc) - then design interfaces along logical groupings (see the Interface Segeragtion Principle).
The interfaces might represent operations from a BL centered perspective - or a "service" based one.
Anyway, to answer your specific question...
I define my equivalent of DTO's in a Common assembly, and the Data Interface in a separate one as well - so I have 4 assemblies: BL, Data Access Inteface definition, the Interface Implementation and Common; all assemblies reference the common one.
I'm working in C#.Net, I define the DTOs as structs (but you could use classes); and all the properties of these are readonly - you feed data into them in the constructor - this way the DTO's are effectly 'dumb' envelopes of information.
Google for domain driven design and the repository pattern. It soumnds like you are headed in that direction with your architecture and depending that the scenario warrants it I would use this approach on more complicated code.