I have a few quick questions about the use of the business logic layer in the average N-Tier architecture application.
I am developing my final year university project, and using a web forms presentation layer, business logic layer, data access layer and data layer.
1) What are your opinions on where is the best place to perform user input validation? To me it makes sense to use the presentation layer with something like jQuery validation for client side, and ASP.NET validation controls for server-side validation - however plenty of articles state it is best to perform validation in the BLL?
2) Currently my BLL is fairly thin, 90% of the classes simply act as an interface to the DAL, however I do know there will be more there eventually. In my DAL I have multiple select commands for each entity, e.g. GetAllProducts(), GetProductsByCategoryID(categoryID), GetProductByProductID(productID), GetProductsBySupplierID(supplierID). This appears to have a low level of business logic involved, i.e. technically there should simply be a GetAllProducts() function, which could be filtered using code in the BLL.
What is your opinion on the best practices for this? One select statement with filtering in the BLL, or as many select statements as needed to get the data I want? I would imagine always selecting every product would get pretty heavy on resources on large scale apps, however at least there is a true separation of logic between tiers.
Cheers,
Stu.
i don't think so you need to have bll. you just need to have two layers. WebUI and DAL.
and the use of linq to sql or lambda expression with Data entity model will be the perfect recipe.
One select statement with filtering in the BLL, or as many select statements as needed to get the data I want?
you should go for filtering in the bll as it is your final pro, if you need to use all the layers. it will so helpfull when u reuse your code. Do make filters in BLL.
Related
I have a ASP.NET MVC solution with three projects:
SquarkMVC
SquarkBLL
SquarkDAL
The SquarkDAL layer has Linq2SQL classes for each object in the DB. BLL references the DAL in order to conduct business logic on the DB.
My question is this... without having to reference the DAL in the MVC layer, how should I model the entities of the DB in the MVC layer? For instance, if I have a sign up form in the MVC layer, what is the best way to take that information, pass it to the Business Layer which then passes it on to the Data Layer? I don't want the MVC layer to know anything about the DAL.
I've found this answer on another post... is it generally agreed that the best way to overcome this is to create a transfer object in order to pass the information from the presentation layer, to the business layer, which will then convert the information into the entity classes used by the DAL?
Hope this makes sense.
Using objects is a common way to do this. Usually DTOs (Data Transfer Objects) are "dumb" POCOs having a set of properties, and acts like a "struct", but, if you put on them validation and more logic (view logic) you have a view model and you can use them to work with the controller. This one should use the model (of the Business Layer).
More, Business Layer should never having a reference to the DAL, because your business model should be independent by the storage.
Instead, the data access layer should reference the model, and choose the right way for persistence. You can achieve it with the Repository pattern.
Anyway there are a lot of books about domain driven design.
So I am thinking of using LLBLGen Pro and Spring.Net on this asp.net project using a service layer to decouple the Business Logic from the Data Store. I am also considering using PONOS in the UI Layer, now my question is:
Should I Map the rich LLBLGen Entity Objects to Ponos in the Data Layer or in the Service Layer? If I do it in the Data Layer then I loose all their rich functionality in the service layer. Or should I just skip the mapping to Ponos and use LLBLGen entities all the way through? If the later it will be harder to test it right?
Can someone give me pros and cons of both approaches?
Thanks
The upside of using LLBLGen Entities with no mapping is that you get entities generated right from your database schema (or even with no database schema in LLBL 3.x), so you can have a very usable entity model in a matter of minutes. The downside is that your entities inherit from LLBL framework classes, which makes them harder to enrich with behavior/business logic. If you generally design your biz logic as a set of services, this won't pose a problem.
I don't see testing as a problem in this scenario, as I generally view the entities as "anemic" data objects, and I generally don't mock such objects (no real reason to do so).
The upside of mapping to POCOs is that you have full control over the design of your domain/entity/DTO objects, and they can be as rich or as anemic as you want. The downside is that you will have to design and code the POCO classes and the mapping, and (as you said) you will lose some functionality like change tracking that is built into LLBL Entities.
I personally choose to use the generated entity objects unless I have a very good reason NOT to.
When it comes to web development I have always tried to work SMART not HARD. So for along time My Aproach to interacting with databases in my AspNet projects has been this :
1) Create my stored procedures
2) Drag an SQLDatasource control on my aspx page
3) Bind a DataList Control to my SQLDatasource
4) Insert, Update & Delete by using my Datalist or programmatically using built in SQLDatasource methods e.g
MySqlDataSource.InsertParameters["author"].DefaultValue = TextBox1.Text;
MySqlDataSource.Insert();
Recently however I got a relatively easy web project. So I decided to employ a 3-tier Model...But I got exhausted halfway and just didnt seem worth it ! It seemed like I was working too HARD for a project that could have been easily accomplished by a couple of SqlDataSource Controls.
So Why Is the N-Tier Model better than my Approach? Has it anything to do with performance? What are the advantages of the ObjectDataSource control over the SqlDataSource Control?
You approached things backwards. The SQLDataSource approach is for small lightweight projects. As soon as you get bigger you'll want to reuse structures and queries between a lot of different pages.
With your approach that means applying the copy/paste design pattern from one page to another just so you can use the same query. Now think what happens when something changes (the DB structure for example) and you have to replicate those changes between 50 pages that all have SQL literals embedded in them - you're in a world of hurt.
Here comes the n-tier model to the rescue - the data access logic should be isolated in its own tier and there should be only one piece of code responsible for a certain business/data logic and if changes need to be done there would be only one piece of code that needs to be changed. The problem with this approach is that it requires more effort up front and the payback is only visible on reasonably big projects.
Here are a couple of reasons for n-tier:
n-tier means better scalability. You can add middle tier servers to scale if the database server can't keep up.
n-tier allows you to add security outside the database (e.g., enterprise directory servers).
n-tier gives you an intermediary that can check for SQL injection, validating and binding variables from the UI.
n-tier can mean looser coupling. SqlDataSourceControl means the UI knows all about the database schema. (This one is shaky - if you add a new field, the effect will ripple through the UI no matter what you do.)
A middle tier makes it possible for another UI to re-use functionality.
If you're just writing a CRUD web app, with no chance to share and good scalability, your approach might be fine.
There is not really any problem with using the SqlDataSource control if you want to. That being said, there are plenty of valid reasons to use an N-tier system.
it tightly couples your presentation
layer to your data layer
you duplicate a ton of work
SqlDataSource queries are often
unique
If you're not building medium or large-sized projects, you've discovered the secret here.
n-tier only helps for bigger applications; below those, it's a practice exercise at best, and a remarkable timesuck regardless.
I have found that when you first begin to prototype your application it is much faster to use the SQLDataSource object. You can move through as a significant amount of rapid web application design using this method first. As your application begins to grow and reflects the need to move to using a web service for database n-tier connectivity, you can then make your decision at that point. Some of the benefits are producing a functional web app to demonstrate to the clients. Once they agree to the design and approach you can make a decision to perhaps convert the queries into a web service.
This is not very difficult as you have already created the queries within the SQLBuilder and you only have to now establish/move these same queries from within a web service, and then call the appropriate web service queries from the UI layer.
This will take time but the prototype web app has already proven the approach is acceptable and has avoided considerable delays messing around we a web service before it is, or perhaps not needed.
i read in one article that its not a good practice to pass dataset between different layers of .net web application.(DAL->BAL->Pages vice versa).Is that correct?
please give your suggestions.
Thanks
SNA
On the one hand, the problem with datasets and datatables is that they expose database implementation details like column names and types outside of your data access layer. Change a column name in your database or query and odds are that change is propogated to your dataset as well, forcing a re-compile of any tier that uses the dataset. So if you retrieve data into a dataset you should convert it to use strongly-typed business objects before passing it on.
On the other hand, a dataset doesn't care what kind of database it belongs to. You can use them with access, oracle, sql server, mysql, anything. So there is some generic-ness there that can make them useful when passing data between tiers. And just like the business layer shouldn't care about database details the data layer shouldn't really need to know what the the business objects are, so there's a good argument that you should use them for data interchange at that level.
My normal procedure is to have a sort of one-way "translation" tier between the business and data access layers, so that the business layer only deals with business objects and the data layer only returns generic data. This currently takes one of two forms:
I'll write my data access methods to return datatables or datareaders, the the translation tier will use a factory pattern to convert those rows into the desired strongly-typed business objects.
or
I'll use C# iterator blocks to convert a datareader into an IEnumerable<IDataRecord> in the data access layer and the translation tier will use them to change that IEnumerable<IDataRecor> into an IEnumerable<MyBusinessObject>, such that the code only ever iterates over the result set one time.
There is nothing wrong with passing around datasets but it's not a great practice.
Pros:
Easy to pass around and use in .NET apps
No having to code wrapper classes
Lots of functionality built into DataSets
Cons:
Data type that is not really type safe.
Your data field names can change all parts of your app will compile fine until they blow up at runtime.
Heavy object. Dataset does a ton of stuff and you probably don't need 90% of it.
Having non .NET apps talk to your DAL or BAL is going to be very clean.
There's nothing wrong about passing DataSets from your DAL to your BAL.
I think this stackoverflow question on DAL best practices sums up the two schools of thought pretty well.
I am in the middle of a "discussion"
with a colleague about the best way to
implement the data layer in a new
application.
One viewpoint is that the data layer
should be aware of business objects
(our own classes that represent an
entity), and be able to work with that
object natively.
The opposing viewpoint is that the
data layer should be object-agnostic,
and purely handle simple data types
(strings, bools, dates, etc.)
There is no problem with passing dataset across layers. If you observe, you will notice that passing dataset is by reference and not by value.So there is no issue of performance here.
Now what you read is also right, but you have to understand the context. If you are passing the dataset across remote boundaries, that is not a recommended practice.
There's nothing fundamentally wrong with that doing that. Although the basic idea of having a DAL, BLL and UI layer is so that each layer can abstract what's beneath it. E.g. the BLL shouldn't have any knowledge of how the database is structured because the DAL abstracts that away. If a dataset is being loaded in the DAL then passed straight through the BLL to the pages, it kind of sounds like the BLL is pointless.
The strongest statements often seen about DataSet is not to pass it into or out of a web service. That goes beyond exposing implementation details, and includes exposing details of the platform (.NET).
Although it's possible to change "table" and "column" names in a DataSet from those in the underlying database, you're still largely stuck with the underlying structure of the database. To abstract that, I would use Entity Framework. It allows you, for instance, to define a "Customer" entity which takes data from multiple tables and puts it into a single entity. Code using the entity doesn't need to know whether it is implemented as one table, two tables, or whatever.
Even there, you should not pass these entities outside of a web service boundary. They still pass implementation details outside of the implementation. For instance, properties of the base classes get serialized, even though these are just implementation details.
As far as I've understood, the DataSet requires the db connection to be open, for as long as it is used, which will reduce performance in your application as it keeps the connection open until the content is rendered.
Instead, I recommend using generic collections, such as IEnumerable<myType> or IQueryable<myType>, where myType is a custom type which you fill with your data.
I was looking for some feedback on the current design.
Here is how it currently looks
Web App (UI) References BLL Layer and BusinessEntities Layer
BusinessEntites Layer - Contains Interfaces and Classes (with internal validations on the properties)
BLL (references the BusinessEntities and DAL Layer) - Has mostly Managers for each of the Business Objects with methods like Create() Save() Delete().
DAL (references BusinessEntities Layers) - Has DB commands that create/add/update Business Entities Objects.
I'm not quite sure about the naming conventions i used for the layers so if anyone has any better suggestions than i'll gladly adopt them.
Also i don't like the idea of the DAL referencing the BusinessEntities Layer, but how else am i going to return objects instead of Datasets/DataTables?
Thanks for any feedback.
With respect to your needing to reference the business layer from the DAL, I would agree that this is probably not optimal -- lower tiers should not know about the ones above them, it reduces reusability and adds extra/potentially circular dependencies.
Have you considered having your business entities "fill themselves up" and do their own persistence operations using the DAL classes, rather than the DAL acting like a factory for them (as in your current design)? That way, your DAL would be a more direct representation of the database, and the business entities would contain the (business) logic needed to fill and persist themselves appropriately.
Also, the "BLL" layer you spec out doesn't really appear to me to contain business logic; it looks to me to be more of a persistence services layer for the entities.
So a variation of what you propose could be:
Web/UI, referencing Business Entities
BusinessEntities, contains interfaces and classes with business logic. References DataServices layer
DataServices, contains classes that load, find and persist data. Can serve up "generic" structures containing the data (Data Transfer Objects) that can be produced, consumed and processed by Business Entities. References DAL.
DAL, which simply provides classes that map to tables.
Depending on your requirements, I would consider merging your BusinessEntities and DataServices (BLL in your original design) into a single tier; the only reason I can think of to split them apart is if you are doing something like Silverlight where you need asynchronous data operations on client-side business entities.
Of course all of this is with an incomplete knowledge of your specific system requirements -- you will need to design what is best for your specific application. Good luck!