I have a a broad-scoped architecture question. I have multiple .net projects and multiple databases all interacting with each other across multiple web applications all for internal use. We would like to create an over-arching layer, somewhere, somehow, to create objects out of the data we query from a database. These objects would have functions/methods available to them, defined somewhere. The question is, what is the most efficient, flexible and advantages/disadvantages of way to define these objects.
For example. Let's say I have multiple HR-related tables: tbl_employees, tbl_departments. When I pull an employee into an application, I then have a whole bunch of code in that project that is associated with that employee, most predominately the functions I can do to that employee - functions such as edit_contact_info or increase_salary or add disciplinary_note. Similar with a department and functions such as edit_department, manage_department_employees. Some functions may include some logic in them, some may just redirect to a particular page.
My question is, how or where or what can I make to classify an employee entry or even series of employee entries as an "object", meaning whenever I pull that "object" somewhere, I also have the associated actions with it. Whether I am pulling the data as a list somewhere or even as part of a data-visualization, I would like to have the appropriate functions/methods available. Even if it is in a different project.
I am looking for different possibilities, not necessarily one answer and I am not entirely sure the best way to go about it although I have thought maybe about creating another layer within the database that holds all the "object" definition data or perhaps some definitely with the .net framework but I lack the expertise to know exactly what I am talking about. From my limited knowledge, I believe I am looking for some sort of ORM (maybe in-memory) implementation, but I am not sure how to get started exactly.
Does anyone have any ideas or a direction to point me in perhaps?
I appreciate any and all help!
Edit
To be clear, what I am trying to find is something I can apply on top of projects and applications I already have up and running and that are being used. I would like a way to implement this over-arching object functionality on top of pre-existing mvc projects
Related
MS stack developer historically.
I have committed to retooling to the following stack
angular -> ms web.api2 -> C# business objects -> sql server
Being old, I develop the database from requirements and use Codesmith to generate the business logic layer. (yes, I have heard of entity framework. even tried it once).
As I embrace Angular and web API 2
I find that Angular wants me to write a model on the front end. This seems to be just a data structure, I cant even add helper methods to it
So I also often write a class with helper methods that takes an instance of the model. Kind of ugly,but it does marry structure and logic.
I find that Web API2 wants me to write a model. This again seems to be just a data structure. I am exploring the dynamic data type, but really this doesn't buy me much. Instead of writing a class, I'm writing a mapping function.
The question is this:
Is there any way around having 3+ copies of each class spread across the stack?
Codesmith is a very capable code generator... it can gen multiple files... but...
If its just a couple data members, and 3 places, I can copy paste edit and get it done.
Just seems to me that now committing to keeping a data structure in synch in 3 different environments is setting oneself up for a lot of work.
I have spent the last 15 years trying to shove as much code as I can into a framework of inheritable classes so I can keep things DRY.
Am I missing something? Are there any patterns that can be suggested?
[I know this isn't a question tailored for SO, but it is where all the smart people shop. Downvote me if you feel honor bound to do so.]
Not entirely familiar with how CodeSmith generates it's classes, but if they are just plain-old-CLR-objects that serialize nicely, you can have WebApi return them directly to your Angular application. There are purists that will frown upon this, but depending on the application, there may be a justification.
Then, in the world of Angular, you have a few options, again, depending on your requirements/justification, and your application - again, purists will definitely frown upon some of the options.
create classes that match what's coming down from the server (more correct method)
Treat everything as "any", lose type safety, and just access properties as you need them i.e. don't create the model. (obviously less correct method)
find a code generation tool that will explore API end points to determine what they return, and generate your typescript classes for you.
Personally, using Entity Framework, I (manually) create my POCO's for database interraction, have a "view"/DTO class that WebAPI would then send back to the client, and a definition of the object in Typescript, but I am a control freak, and don't like generated code.
I need to access some data in an existing sql-database and publish it using a REST-Service (using Webapi).
In my previous, very small project I just accessed the EF-Context directly from my controllers, create some DTO's from my EF-Entities and return it to the caller. That was simple and I got it working really fast.
Now, the project is not much bigger but I want to do it 'the right way' this time as everyone is talking about a layering architecture, even for a small project, so unit-testing etc. is much easier.
Being a newbie on this (yes, I need to read more books) I decided to start reading tons of blog-posts about architectural design of an application and so on.
First thing was to get in touch with the various techniques on accessing the data in the database using EF (I'm using v6.2, DB-First). Some say, you need a repository for each entity, some say, create a generic repository and others say, repositories are the new evil, avoid them at all cost.
Some blog-posts I've read:
generic-dal-using-entity-framework
is-the-repository-pattern-useful-with-entity-framework
repositories-on-top-unitofwork-are-not-a-good-idea
why-entity-framework-renders-the-repository-pattern-obsolete
favor-query-objects-over-repositories
and so on.
Even some others say, that separating your EF-generated POCO's should be separated from the 'pure' EF-stuff like the EDMX: splitting-entity-framework-model-classes-separate-projects
Some of the posts are old and may be obsolete but I'm just struggling on what is the best way to accomplish my task.
Right now, I have 4 Projects:
DGO.Core: Containing my DTO's
DGO.Data: Containing my EF-Stuff and 1 Repository-Class (see below for details).
DGO.Service: Referencing DGO.Data and accessing the methods exposed by the repository-class.
DGO.Webapi: Referencing all three DLL's but using the methods from the Service-Dll.
I need to reference the Data-Dll to be able to inject the data-repository.
So now my db-queries reside in the Data-DLL (in the so-called repository-class) which creates filled DTO's from my Core-DLL. These DTO's are then passed to the Service-DLL, which might process some logic here and there and then this DTO is passed to the Webapi-Controller.
Is this a common approach on passing these DTO's thru all layers?
Or is it better to split the POCO's from the EDMX and use these directly in my service-layer.
So the direction will be 'Data-Layer' -> 'POCOs' -> 'Service-Layer' -> 'DTOs' -> Client (Controller etc.).
And where should the queries take place? I think, in the Data-Layer but some say, it should be done in the service-layer. I think, the data-layer is responsible for querying the data and the service-layer is responsible for 'working' with the data.
Hope, I made my problems clear. Could provide code if it's necessary.
Thanks!
I don't know the difference between Business Entities and Business Objects
But what I have is a class that has some properties and I'll add an IsValid method later.
That's what Application Architecture Tutorials taught me
But it just hit me, what's the difference between using this approach and just sending/receiving my data through my layers without storing them in objects .. and when I add an item to the database, instead of creating an object of the item's type then store it and send it to the BLL or the DAL, I would just send the information I just collected as it is, as an argument to my BLL methods!
I'm sorry if my question is a bit confusing. But I hope that you'll excuse me as this question and the application architecture is a just a very big ocean ..And I'm LOST! =S
P.S: I added the technologies I'm using, Hoping it will help you understand my environment
The bottom line is that either way can work--it's possible to pass your data around as a series of parameters and make it work. There are even situations where it might be more derirable to do it that way (e.g. a really simple application).
That said, it's generally accepted that it's easier to code and maintain an object or set of objects that represent your data than it is to pass multiple (possibly many) parameters through every method call and layer of your application.
This concept is called encapsulation, and is one of the core principles of Object Oriented Programming. A quick google will probably answer your question more completely.
In some projects I see that a dummy record is needed to create in Db in order to keep the business logic go on without breaking the Db constraints.
So far I have seen its usage in 2 ways:
By adding a field like IsDummy
By adding a field something called ObjectType which points a type: Dummy
Ok, it helps on what needs to be achieved.
But what makes me feel alert on such solutions is sometimes you have to keep in mind that some dummy records exist in the application which needs to be handled in some processes. If not, you face some problems until you realize their existence or until someone in the team tells you "Aha! You have forgotten the dummy records. You should also do..."
So the question is:
Is it a good idea to create dummy records to keep business logic as it is without making the Db complain? If yes, what is the best practice to prevent developers from skipping their existence? If not, what do you do to prevent yourself from falling in a situation where you end up with an only option of creating a dummy record?
Thanks!
Using dummy records is inferior to getting the constraints right.
There's often a temptation to use them because using dummy records can seem like the fastest way to deliver a new feature (and maybe sometimes it is), but they are never part of a good design, because they hide differences between your domain logic and data model.
Dummy records are only required when the modeller cannot easily change the Database Definition, which means the definition and/or the data model is pretty bad. One should never end up in a situation where there has to be special code in the app layer to handle special cases in the database. That is a guaranteed maintenance nightmare.
Any good definition or model will allow changes easily, without "affecting existing code".
All business logic [that is defined in the Database] should be implemented using ANSI SQL Constraints, Checks, and Rules. (Of course Lower level structures are already constrained via Domains/Datatypes, etc., but I would not classify them as "business rules".) I ensure that I don't end up having to implement dummies, simply by doing that.
If that cannot be done, then the modeller lacks knowledge and experience. Or higher level requirements such as Normalisation, have been broken, and that presents obstacles to implementing Constraints which are dependent on them; also meaning the modeller failed.
I have never needed to break such Constraints, or add dummy records (and I have worked on an awful lot of databases). I have removed dummy records (and duplicates) when I have reworked databases created by others.
I've never run across having to do this. If you need to do this, there's something wrong with your data structure, and it's going to cause problems further down the line for reporting...
Using Dummies is dumb.
In general you should aim to get your logic right without them. I have seen them used too, but only as an emergency solution. Your description sounds way too much like making it a standard practice. That would cause more problems than it solves.
The only reason I can see for adding "dummy" records is when you have a seriously bad app and database design.
It is most definitely not common practice.
If your business logic depends on a record existing then you need to do one of two things: Either make sure that a CORRECT record is created prior to executing that logic; or, change the logic to take missing information into account.
I think any situation where something isn't very easily distinguishable as "business-logic" is a cause for trying to think of a better way.
The fact that you mention "which points a type: Dummy" leads me to believe you are using some kind of ORM for handling your data access. A very good checkpoint (though not the only) for ORM solutions like NHibernate is that your source code VERY EXPLICITLY describes your data structures driving your application. This not only allows your data access to easily be managed under source control, but it also allows for easier debugging down the line should a problem occur (and let's face it, it's not a matter of IF a problem will occur, but WHEN).
When you introduce some kind of "crutch" like a dummy record, you are ignoring the point of a database. A database is there to enforce rules against your data, in an effort to ELIMINATE the need for this kind of thing. I recommend you take a look at your application logic FIRST, before resorting to this kind of technique. Think about your fellow dev's, or a new hire. What if they need to add a feature and forget your little "dummy record" logic?
You mention yourself in your question feeling apprehension. Go with your gut. Get rid of the dummy records.
I have to go with the common feeling here and argue against dummy records.
What will happen is that a new developer will not know about them and not code to handle them, or delete a table and forget to add in a new dummy record.
I have experienced them in legacy databases and have seen both of the above mentioned happen.
Also the longer they exist the harder it is to take them out and the more code you have to write to take into account these dummy records which could probably have been removed if you just did the original design without them.
The correct solution would be to update your business logic.
To quote your expanded explanation:
Assume that you have a Package object and you have implement a business logic that a Package without any content cannot be created. YOu created some business layer rules and designed your Db with relevant constraints. But after some years a new feature is requested and to accomplish that you have to be able to create a package without a contnent. To overcome this, you decide to create a dummy content which is not visible on UI but lets you to create an empty package.
So the at one time to a package w/o content was invalid thus business layer enforced existence of content in a package object. That makes sense. Now if the real world scenario has changed such there is now a need VALID reason to create Package objects without content it is the business logic layer which needs to be changed.
Almost universally using "dummy" anything anywhere is a bad idea and usually indicates an issue in implementation. In this instance you are using dummy data to allow "compliance" with a business layer which is no longer accurately representing the real world constraints of the business.
If package without content is not valid then dummy data to allow "compliance" with business layer is a foolish hack. In essence you wrote rules to protect your own system and then how are attempting to circumvent your own protection. On the other hand if package without content is valid then business layer shouldn't be enforcing bogus constraints. In neither instance is dummy data valid.
When designing both the domain-model and class-diagrams I am having some trouble understanding what to put in them.
I'll give an example of what I mean:
I am doing a vacations scheduler program, that has an Administrator and End-Users. The Administrator does a couple of things like registering End-Users in the program, changing their previleges, etc. The End-User can choose his vacations days, etc.
I initially defined an Administrator and End-User as concepts in the domain-model, and later as classes in the class-diagram.
In the class-diagram, both classes ended up having a couple of methods like
Administrator.RegisterNewUser();
Administrator.UnregisterUser(int id);
etc.
Only after some time I realised that actually both Administrator and End-User are actors, and maybe I got this design totally wrong. Instead of filling Administrator and End-User classes with methods to do what my Use-Cases request, I could define other classes from the domain to do them, and have controllers handle the Use-Cases(actually, I decided to do one for each Use-Case). I could have a UserDatabase.RegisterNewUser() and UserDatabase.UnregisterUser(int id);, for example, instead of having those methods on the Administrator class.
The idea would be to try to think of the whole vacation-scheduler as a "closed-program" that has a set of features and doesn't bother with things such as authentication, that should be internal/protected, being that the only public things I'd let the outside world see would be its controllers.
Is this the right approach? Or am I getting this totally wrong? Is it generally bad idea to put Actors in the domain-model/class-diagrams? What are good rules of thumb for this?
My lecturer is following Applying UML and Patterns, which I find awful, so I'd like to know where I could look up more info on this described actor-models situation.
I'm still a bit confused about all of this, as this new approach is radically different from anything I've done before.
I would not say that your design, as you speculate, is totally wrong, in fact Administrator and End-User are valid domain objects that should be represented somehow in the Class Diagrams. Just because you identify those two entities as actors doesn't mean they should be excluded from the Domain, remember, your domain is your scope, or "relevant context", that is, the set of useful objects that play a relevant role in your solution.
You may start with basic objects that comprise your model, just write them down, without further analysis, like brain storming...
Vacation
Location
Travel Agent
Schedule
User
Reservation
Reservation Service (This can be an interface for accessing the vacation reservation stuff)
Then try to establish the relationships between those objects, if you can not find any relationship that means you are not choosing the right objects, if they are part of the same problem domain then they must be related somehow.
After some time, you will discover that there are objects missing, try to encapsulate as much as possible, and represent the correct abstractions, Design Patterns might help you out with that.
When every possible object is represented with all its properties and methods, then you should have a fully, although not yet finished, functional design.
I know you should have a lot of theory in your mind, so get going, without fear, I myself have used this approach successfully many times at work.
Finally get a copy of UML Distilled
Regards,
I think you should learn more about domain modeling and process of getting from use cases to class diagrams. Actors as classifiers can be part of class diagrams, however for class diagrams used for analysis and design are modeling the system you develop and an actor is external entity. When you are using use cases and use case diagrams, the goal is to identify functional and non-functional requrements, therefore define the scope of the system to develop and external entities - roles or systems - interacting with the system you are developing. In use case diagrams you can find sometimes a box representing system boundary, which encompasses all use cases, which will be realized in your system, but actors are out of the box. When domain modeling, you usually forget about the system altogether, because you want to capture the way the domain works. Often special diagrams and modeling elements are used for domain modeling. As I said, the point is to understand the domain in which the system will be used. Class diagrams in the analysis and design phase describe the system you are developing, so no actors can be inside.