In a 1 tier application i.e Mvc, you get a folder called models and you build and store your classes in there, I'm aware when it comes to a three tier application from what I have read it seems correct to store the models inside the business layer (2nd tier), and from the UI (first tier) I would add a project reference to the 2nd tier which will allow me to use the models and make calls to methods.
From the second tiers perspective it would call the data layer (third tier) and perform crud operations against the database, but the data layer would require the models from the business layer so when I try to add a project reference from data layer to business layer i get the error
A Reference to "Business Layer" could not be added, adding this project as a reference would cause a circular dependency
Which I understand as a reference has already been made via business layer to data layer
How would I get around this? do I create additional models in the data layer and populate them with results from the database and pass that back to the business layer which then passes it back up to the UI? I'm slightly confused on this.
** Update **
From what I have read for the data layer to reference models inside the Business layer I would need to do model mapping, My model mapping will be quite large so I'm thinking of including a 4th tier which will be a shared library and that will consist of all the models that way the data layer and the business layer can access the models as and when is required.
A little off topic but ...
Depending on the size of your application, there may be no reason to introduce unnecessary complexities to try and follow pattern you may not necessarily understand. Doing so, will cause you extra headache.
That being said, if your project is of a large size and requires some good organizing, I would strongly suggest more research and maybe a few sample project in where you try out the architecture you came up with. No way you'll get it right the first time.
I would personally suggest looking into "onion architecture" instead of "n-tier", and of course you'll find many different views on it. You'll have to make your own decisions.
Here's a generic set-up I would start off with.
Core. It knows about no other project. This is where your classes with your "business" go. Such as Customer, Product, Order, etc.
Data. It knows about Core. It is responsible for taking in a Core object and storing it somewhere. That is all.
Service. It knows about Core AND Data. It's job is to expose methods such as "Create Customer", it will be responsible for creating a customer and storing it.
Web / Api / Mvc. This will know about Service. It's job is to expose your service to the user. (UI and such). (It may also know about Core / Data ... but that's a larger discussion.)
You're on the right track but I find it easier to think of the model layer as the data (third tier), the controller (business layer, second tier) manages the flow of the data between the ui (first tier) and the data layer.
If you modify your architecture this way, you should get rid of the circular references.
This also allows you to map your data layer objects to the appropriate less/more complex structures of the middle tier in a way which simplifies the interface shown to the UI and encapsulates the business logic there too.
I want an opinion from technocrats,
We are migrating legacy system build in Oracle forms using Oracle 8i
database. Client wants to redevelop this legacy system in web
application so we choose MVC3 framework. Client wants us to re use all
stored procedures of legacy system, which contains business logic of
application.
If every business logic is written in stored procedure than i think we
don't need a Business layer in our system.
So i created three layers -:
Interface Layer -> MVC 3 application
Data Layer -> Used to fetch information from stored procedure
DTO Layer -> Used to transfer data from Interface layer to Data Layer.
I did not created Business object or business layer , since all
business logic is inside Stored procedures. I don't like creating
business layer who just forward request from Interface layer to data
layer and don't have any business layer in it.
Is this approach is correct ?
Business layer is separate project
If the business layer is a separate project, I would focus on the portions which are part of the project. It is entirely reasonable to have an interface layer, with minimal business logic (usually validation logic) in a server side application. You might want minimal business logic in the client to make it more responsive i.e. it doesn't go all the way back to the database to validate input.
You can have the business layer in the database (not that I would do such a thing), or in server side Java, or some of it in the client (not that I suggest doing that either to a significant degree)
I would recommend that you still create a business layer even if it just forwards all the operations to the stored procedures which are part of the data layer.
Since the client wants you to reuse all the stored procedures that have the business logic in them it also sounds reasonable that he will not want you to modify or add any more stored procedures. Events may occur that will require you to implement them differently or change the sequence of a business logic that you can then put into your business layer. Maybe you may need a business logic that is not data-centric - meaning it does not sound reasonable to have it in a stored procedure, like sending an email or coordinating with a third party system.
I am writing an ntier website which contains a table of information. I am using jeditable to make the table editable.
The client wants some fields in the table readonly depending on whether the information they contain is before or after a particular date. Should the readonly logic reside in the business layer or the ui layer?
Regards Si
Both. Your UI should check those non-editable fields an then no provide controls to modify the fields and also, for security, your business layer should also disable that functionallity.
Business layer. The before or after date rule could change - it's business logic.
The business layer should execute the rule and communicate the fact to the UI layer. It should be enforcing the immutability on its end regardless of what the client does.
I have been a little confused with trying to determine where to put the business rules for my application.
I am developing an web application using asp.net conventional web forms (not mvc) and on top of that I have a class library where I have the repository pattern for writing to database. I have a "Business Layer" in the repository pattern and also, I am writing stored procedures to affect the tables.
Where should I put for example, Mandatory field validation rules ?
Other example would be, converting foreign currency to USD (i have an exchange rate table, currently I do it in sprocs).
Would you recommend staying away from the sprocs for rules and build everything in my repository business layer ? or In what cases do you recommend building rules and validations within the sprocs ?
This answer is appropriate if you develop a small application that does not use multiple data sources or does not have an extensively unit-tested business layer and if you do not plan to add a service layer (such as for caching). See the opposition in the comments.
If I may, I can suggest to:
Remove repository pattern completely. Do you really need to support multiple databases?
Keep business logic in a business layer, not database. The benefits are in the locality of the rules. All your domain is expressed as a set of conditions, rules, strategies etc. And it is all located in one place. Should you choose to store them in a database you would create yourself additional headache when maintaining the code.
It is easy to unit test code that is in the business layer. I am not sure if it is possible to unit test SP.
SP and Repository pattern don't go well together.
Currency rate change every fraction of a second, for this you should use a reliable web service that you can call and get a precise value.
Summary:
Stay away from SP
Stay away from repository pattern
Use ORM directly instead of repository pattern abstraction
Don't mix persistence and business rules
Separate your business rules in a separate (reusable) assembly
Your repository is NOT supposed to have a business layer. It's sole purpose should be to act as an abstraction of your database. Inside it you manage how you store/retrieve your application data.
Use SP for database operations that are not subject to frequent change. NEVER put your business logic inside SP. Business logic have tendency to change over time.
You can create a domain-layer where your business objects reside. Your business object should encapsulate their own validation logic.
Other than your business/domain objects you may have utility classes (e.g. CurrencyManager or CurrencyHelper) that actually use your business objects to verify business logic against data.
Finally try to keep your domain free from any sort of presentation/view layer reference. Don't apply business validation rules at view layer or display validation logic at domain layer.
-hope that'll shed some light.
Say you have 3 layers: UI, Business, Data.
Is that a sign of poor design if Business layer needs to access Sessions? Something about it doesn't feel right. Are there any guidelines to follow specifically tailored to web app?
I use c# 2.0 .net
No. If you had a "Controller" layer, you should access it there. Get what you need from the Session and hand it off to your business layer.
Sigh.
The broad consensus is going to be no; the business layer and the controller/web layer ought to be maintained differently, because they are separate concerns.
The fact is, you seem to label this as a "purity vs. reality" question which is incredibly short-sighted and slightly obnoxious. It also defies the point of asking the question; if you're not going to consider the opinions being presented, then why solicit them?
It's true that separating things out a little more carefully up front requires more up-front effort, more time, and ultimately may cost a little more. It's also true that you may not be able to perceive any immediate benefit from doing so. However, a wealth of sob stories shared among a huge number of programmers for several decades suggests that, where possible, your so-called "purity" reduces the pain when, five years down the line; gosh; you really have to knuckle down and do a bit of refactoring, and it's not remotely pleasant because of all the cracks through which your responsibilities are seeping.
A slightly better way of envisioning the layers for a web application might be to consider presentation, interaction, business rules and data; from top to bottom. Your data is the database, data access, etc. and the business rules enforce any additional constraints on that data, handle valiation, calculation, etc. Interaction then branches between the presentation layer (which is basically your user interface) and the business logic, performing the use cases that drive your application.
Up to this point, the user interface is all immaterial; it doesn't matter if the user's entering, say, customer data in a command-line application, or navigating some multi-page web form with data stored in the session. Let's say you pick the latter; stick a web front-end on it. Now what you're concerned with is writing relatively simple code to handle retrieving the requested data and presenting it to the user. The point is, your web application; the front-end, that is your entire user interface; sessions and all. Only at the point where you're ready to say, "hey, let's stick that customer data into the database" do you go and invoke those oh-so-lovingly-crafted service layers, passing each bit of information that your web application's got stashed; the user input, the name of the user making the change; all that crap. And your service layer deals with it. Or, alternatively, bitches 'cause you forgot a required field.
Because you've cleanly separated things out, the guts of your application can, as others have suggested, be remodelled (or "borrowed") to use in any other application, and the service layer remains, stateless, clean, and ready to handle things. And it does your validation, and so your validation is consistent everywhere. But it doesn't know who's logged into the web frontend, or the console application, or the fancy rich client application running on a terminal, and it doesn't care, because that detail is important only to those applications.
Need to add a new validation rule? No problem; make the service layer do the validation, and handle the user interface concerns as necessary higher up in the chain. Need to change the way something's calculated? Change that at the business layer. Nothing else needs to be affected.
Smells funny to me. Maybe you need a presentation layer to manage the session and any other stateful information?
I think the Business logic should not be tied to a presentation choice, and if Session lives in that tier it will be tied.
I consider unnecessary usage of Session to be a code smell in general, often querystrings, cookies and viewstate are lighterweight and have better 'scope'
As to Sessions role in a business tier, it depends on what architectural guru you're reading at the moment. If the business logic tier is a place for code independent of UI, then Session isn't a thing to introduce into the business tier.
For example, in a Console app, an ASP.NET web App, a Windows Service, and a Windows Forms app--only ASP.NET has Session.
That said, being able to support mutliple UIs is a highly overrated feature and it doesn't take perfect foresight to estimate if you will ever port your app to a different user interface. If you're highly confident that your logic will only run in an ASP.NET app from now and forever, then it is okay.
An exception would be unit testing. nUnit test runners constitute a different UI and it is hard to simulate Request, Response, Session, Application, etc.
My feeling is that the business layer is the only place to put the session data access because it really is part of your logic. If you bake it into the presentation layer, then if you change where that data is stored (lets says, you no longer want to use session state), then making a change is more difficult.
What I would do is for all the data that is is session state, I'd create a class to encapsulate the retrieval of that data. This will allow for future changes.
Edit: The UI should only be used to do the following:
1. Call to the business layer. 2. Interact with the user (messages and events). 3. Manipulate visual object on the screen.
I have heard people consider the session data access as part of the data layer, and this is semantic, and depends on what you consider the data layer.
If you keep the three layers you listed, the 'Business' layer would likely be the most suited to dealing with Session objects.
Since a session has more to do with the actual framework tying the application together than with any actual business logic, you may want to create a control layer that translates data from the Session object to business data inputs to the business layer.
I think it depends on the usage, but yes, we access session from our business layer all the time. There's a "purity vs. reality" argument here too.
For example, in our application we have a database per client, but one code base. So we have the client info in the session for each user. Sure, we could then pull that data out of session in the web layer and then pass it down to the business layer. Of course, the business layer doesn't even care about it, but it's needed by the data layer to connect to the correct database. So then the business layer would need to pass it down to the data layer. Seems like lots of parameter passing for no good business reason. In our case our data layer checks the session object for the connection string and runs from there. We coded around the issue of not having session if it's not a web app (and we have windows services and .exe helper apps) as follows:
protected virtual string GetConnectionString()
{
string connectionString;
string connectionStringSource;
//In app.config?
if (ConfigurationManager.AppSettings[_ConnectionStringName] != null &&
ConfigurationManager.AppSettings[_ConnectionStringName] != "")
{
connectionString = ConfigurationManager.AppSettings[_ConnectionStringName];
connectionStringSource = "Config settings";
}
//Nope? Check Session
else if (null != HttpContext.Current && null != HttpContext.Current.Session &&
null != HttpContext.Current.Session[_ConnectionStringName])
{
connectionString = (string)HttpContext.Current.Session[_ConnectionStringName];
connectionStringSource = "Session";
}
//Nope? Check Thread
else if (null != System.Threading.Thread.GetData(
System.Threading.Thread.GetNamedDataSlot(_ConnectionStringName)))
{
connectionString = (string)System.Threading.Thread.GetData(
System.Threading.Thread.GetNamedDataSlot(_ConnectionStringName));
connectionStringSource = "ThreadLocal";
}
else
{
throw new ApplicationException("Can't find a connection string");
}
if (debugLogging)
log.DebugFormat("Connection String '{0}' found in {1}", connectionString,
connectionStringSource);
return connectionString;
}
Accessing the session from the business layer is definitely a code smell.
If you need to 'switch' the business layer as stated, your presentation layer or controller is all that need to worry about what the session variable is.
For example, say you want to use one set of objects for one session variable and another set for another variable. Your controller could call a service layer and pass in the variable. The service layer would then return the appropriate business object.
Your business layer has no business knowing anything about the session in the same sense that your presentation layer has no business knowing about how you are connecting to the DB.
The session object is tied to a specific UI implementation, so having your business layer died to your session is a smell.
Plus, you probably should be able to unit-test your business layer - how are you going to do that if there are dependencies on a session?