I am working on maintaining an ASP.NET website, and I've noticed the business layer and other supporting libraries make heavy use of HttpContext.Current.Session. This makes it hard to keep track of session variables, to determine what they're used for and why they even exist.
Is it considered bad practice to use the session in the business layer? And would it be wise to start moving all code that uses the session into the code-behind?
It's almost never a good idea. There's lots of reasons, but here's a couple:
you'll never be able to use business layer code in anything other than ASP.NET
Unit Testing becomes much more of a pain or even impossible.
We ran into huge headaches with this exact same situation when we started to build services that utilized common business layer code.
I follow this rule - any class in System.Web namespace (javax.servlet package in Java) should not be present in your business layer.
Yes - the BL should not have any knowledge about the Session. Its a dependency that you don't need.
make a class that is an indirection, in which case on the web it may return values from HttpContext.Current.Session, and in other areas would resolve that from somewhere else. IE have an interface ISessionStore and have concrete classes WebSessionStore and WindowsFormsSessionStore, etc.
this will make your code easier to test and also gives you expansion paths when say, you now want x business logic to run in a windows service where it can run x piece of code every y minutes.
In my opinion it is bad practice.
It makes it pretty hard to dissociate that business layer from the environment. If you expect to unit test the thing for example, you're out of luck.
One way to take care of that simply would be to insulate this into an abstraction for now, so that you can pass a "state cache" around and not refer to HttpContext. That will take you at least to some degree of abstraction.
Another more interesting question is, why does the business layer need to refer to that?
its always better to have a centralized Cache/Session manager which encapsulates the complete interaction with session/cache or whatever persistence method you use. having your BL to interact with sessions is definitely a very bad practice and in a way defeats the purpose of the tiered architecture altogether.
Related
I'm looking for suggestions regarding implementing process flow / work flow management in a PureMVC based application.
Our Flex application includes a number of processes such as account creation, payment processing, etc.
Within our team, there is some discussion of how rigidly we should adhere to the PureMVC model.
Within the PureMVC model, it seems reasonable that the current state in the process could be managed in a Proxy.
Commands are clearly responsible for processing the actions required of each node and for node transitions.
Mediators for managing the UI.
However, I think that there is an important bit still missing here: a ProcessController.
The approaches we've reviewed all seem to either violate the PureMVC model (even just slightly) or make unreadable code.
A proxy would maintain the state of the process. As such, it seems to be an appropriate way to implement the controller. However, this is putting a lot of business logic into the proxy.
The Mediator space makes more sense, but the controller in that space would not necessarily directly interact with any particular UI element but would instead coordinate/delegate to dedicated Mediators.
Yet another model would have us put process transition information into Commands. While this seems to be the best place for that work (given the role of commands relative to proxies and mediators), this approach looks to make some particularly heinous looking code with process transition logic distributed among scores of commands.
So how have others handled this problem?
Thank
Curtis
This is exactly the problem that PureMVC StateMachine Utility (and Finite State Machines in general) are meant to solve.
In a simple XML format, you can define states, valid transitions to other states, and the actions that trigger those transitions.
It is all notification-based, so you send StateMachine.ACTION notifications that cause the StateMachine to execute any entering/exiting guard logic that may be necessary (e.g., only allow exiting the FORM_ENTRY state if all the data valid, or only allow entry into the FORM_PROCESSING state if the user has admin rights, etc.). If a state change occurs, notifications are sent that can be used to organize the view or execute logic upon entering the new state.
Here is a StateMachine Overview presentation that will give you a better idea
http://puremvc.tv/#P003/
I think your idea of 'ProcessController' is probably the better way of doing it. Personally, I'm not a fan of PureMVC and don't use it because it doesn't allow enough flexibility or extension points to help with such problems.
Frankly, it's hard to advise on your issue because I don't know exactly what you're trying to accomplish. I do agree that the concern needs to be handled by one object. If you can, try to create a model that can store the data for the process and have another class just manage it throughout. Not sure if that makes sense, but then again, your problem isn't very clear either.
As an added extra, I would look into Dependency Injection. I'm trying to remember if PureMVC does it (I don't think it does), but with DI it would of been a fairly simple problem to solve. Frameworks like Parsley and Robotlegs are really good at that.
In pureMVC the State Machine Utility is probably the best choice for a process controller - and btw, according to the Implementation Idioms & best Practices doc. for PureMVC, it's perfectly fine to have mediators that don't manage a visible component
The majority of the Application Architecture advice seems to advise strongly that only Presentation Layer should have access to HTTPContext (to promote loose coupling, decrease dependencies, increase testability etc).
So, how do people deal with Caching and Session? Very specific DataAccess and Business Logic knowledge is required to determine what items need caching to best benefit application performance. However, and an ASP.Net web application, access to these is provided via the HTTPContext.
One option would be to create a CacheFactory and a SessionFactory, and an ICache and ISession interface - and then somehow use DI principle to pass and ISession and ICache to each method in the BLL and subsequently DA Layer that needs it.
Is this really what developers end up doing? Is there another, easier, way to deal with this?
Thanks for any advice.
Personally, if I'm developing for ASP.NET (web) only, and I know the class libraries are only going to target the web, I have no issues referencing System.Web or any other assembly as needed. Sometimes practicality should come first.
On the other hand if you know, or are unsure if the BLL, DAL or other layers may be reused in a client-server or other environment, you may need to look at using a more flexible approach such as a session handler interface, etc.
The main thing is you clearly understand what best practice recommends. At that point you can make rational decisions about what should apply to each project or situation. It won't always fit like a glove.
In my experience caching is done ata certain layer - and what you're caching applies within the scope of that layer, so:
You might cache data in the DAL so that the DAL returns it from memory and not by hitting the DB again; so here we're caching "raw" data at the data level.
The BL might cache similar data (say POCO's) - in other words "logical" data that has had BL applied to it; so here we're caching BL data in the BL level.
Your UI might cache (you guessed it) information that is built at the UI layer - liek a presentation of data as a webpage, XML, etc.
When you look at caching, as the architect / designer of the system you'll make decisions about what things are worth caching, generally this will be driven by a need to balance:
Performance needs to hit a specific target.
What time (and cost) options you have.
Assuming we're caching to increase performance, you'll want to analyse your system and identify the bottlenecks that need to be removed or avoided - the first pass of this analysis should at least identify which layer to focus on first.
Another thing to consider is that the more you can cache closer to the consumer - the less overall processing there is that needs to occur; in otherwords, if you can cache at the UI layer then the BL and DAL layers won't even get a look-in (you won't need to add caching there).
At this point I want to ask you what exactly it is that you're trying to achieve.
While everything I've said is true (as far as I am aware) it's all based on the assumption that we're delivering "vertical" slices of the systems functionality (like "creating an invoice", "adding a product" etc); there's another model you can apply - the cross-cutting concerns model.
Think about something like logging - every part of you system (UI / BL / DAL) should be able to log system events; my favourite tool for this is the MS Enterprise Libraries (MSEntLibs). When I work with them I consider them to be a "black-box" - a self contained unit. I (by choice) have no idea how they are architected - the thing that is important is that they are isolated and have dependencies which are relativly easy to manage.
The MSEntLibs can log to a database, but if I call an MSEntLibs logging method (to log to the DB) direct from my UI (and skipping over my BL) I don't care.
So depending on what you're trying to do the right anmswer will either be:
Simply identifying what needs to be cached at letting the appropriate layer handle it.
You don't need to try using DI to pass stuff to you BL at all - a cross-cutting black-box component might be appropriate?
Does data binding fit in a 3 layered architecture? Is dropping a grid-view on a web form and binding it to a LinkDataSource or SQLDataSource considered bad? The way I see it, that's the Presentation Layer talking to the Data Access Layer. I once heard a "professional developer" say never ever do this, so what's the alternative if you shouldn't?
The way you are doing is ok if it is a small project, but if you want your app. to have flexibility to support Windows/ Web in future then you must use Layers.
Please follow this link http://www.dotnetspider.com/resources/1566-n-Tier-Architecture-Asp.aspx
You should have a middle tier between Presentation and Data Access layers, the middle tier is pulled out from the presentation tier and, as its own layer, it controls an application’s functionality by performing detailed processing.
The main task of Business layer is business validation and business workflow.
When you build your business logic components into an SDK, you are effectively disconnecting it from your Web application, and any input validation that it performs. Therefore, your business logic components are the last line of defense to make sure that only valid values make it into your database.
Databinding is, of course, necessary to effectively dispay data.
Tooling is great and can boost productivity. It is equally important to understand what the tooling is generating, even at a basic level, in order to be able to effectively utilize the generated code.
The reaction you describe seems a bit extreme. If a wizard can generate some code that works for ya, then use it. If you don't understand the generated code then that is the next priority; learn about what it is doing and why. In the meantime, you have a page that people can put eyes on regardless of how it got there.
I am a bit pragmatic when it comes to tools. You do what you have to do. But, if after [insert appropriate internship length] you are still using code gen and cannot customize or fix it then you (as in the royal you, not the you you) are being lazy or stupid or both. ;-)
OT:(almost) Never say never unless you want to lessen the impact of what you are trying to communicate.
my 2 pesos.
When you're doing a small project or a prototype, go with the LINQDataSource or SQLDataSource. However, the downsides of those data sources are serious enough for you to think hard if they are appropriate. If your doing a multi-layered or multi-tear architecture, they simply don't fit. But even if your architecture isn't that strict, you should ask yourself how big this application is going to be and how likely it is going to be that you will make changes to the system in the future. How much time it is going to take you when you want to make a change to the database?
I've seen projects were the developers used those data sources, because those were the constructs that were used in those nice ASP.NET video's. However, when the projects grown from prototypes to big production applications (yes, I’ve seen it happen, the prototype seemed good enough), the lack of compile time support (your queries are defined in markup!) made it very hard to do any change to the system.
When you need to make a change to the system, that will be the time that you’ll see that the cost of the change is a magnitude bigger than the time you saved by flattering your architecture.
New to .net and was wondering if there is a performance gain to keeping an instance of, for example a DAL object in scope?
Coming from the Coldfusion world I would instanciate a component and store it in the application scope so that every time my code needed to use that component it would not have to be instanciated over and over again effecting performance.
Is there any benefit to doing this in ASP.Net apps?
Unless you are actually experiencing a performance problem, than you need not worry yourself with optimizations like this.
Solve the business problems first, and use good design. As long as you have a decent abstraction layer for your data access code, then you can always implement a caching solution later down the road if it becomes a problem.
Remember that any caching solution increases complexity dramatically.
NO. In the multi-tier world of .asp this would be considered a case of "premature optimization". Once a sites suite of stubs, scripts and programs has scaled up and been running for a few months then you can look at logs and traces to see what might be cached, spawned or rewritten to improve performance. And as the infamous Jeff Atwood says "Most code optimizations for web servers will benifit from money being spent on new and improved hardware rather than tweaking code for hours and hours"
Yes indeed you can and probably should. Oftentimes the storage for this is in the Session; you store data that you want for the user.
If it's a global thing, you may load it in the Application_Start event and place it somewhere, possibly the HttpCache.
And just a note, some people use "Premature Optimisation" to avoid optimising at all; this is nonsense. It is reasonable to cache in this case.
It is very important to do the cost benefit analysis before caching any object, one must consider all the factors like
Performance advantage
Frequency of use
Hardware
Scalability
Maintainability
Time available for delivery (one of the most important factor)
Finally, it is always useful to cache object which are very costly to create or you are using very frequently i.e. Tables's Data (From DB) or xml data
Does the class you are considering this for have state? If not, (and DAL classes often do not have state, or do not need state), then you should make it's methods static, and then you don't need to instantiate it at all. If the only state it holds is a connection string, you can also make that property field a static property field, and avoid the requirement of instantiating it that way.
Otherwise, take a look at the design pattern called Flyweight
I have started design of a ColdFusion application that is entirely web based. Not much use of Flash forms, or AJAX.
The first version is a strict web app. Version 2 will be a Flex front end.
I want to design and build things so that the Flex layer can use existing logic. It's okay if it means I have to do extra work in version 1. I would like to harden the logic code once and not re-factor.
What are things worth considering / designing / implementing now that would greatly aid in being able to design an app in this way?
One big suggestion, depending on where you're coming from (as it's a rather big question), would be to leverage the ColdFusion component (CFC) as much as possible; the CFC architecture is excellent, versatile and powerful, it integrates quite nicely with Flex (and will do so even better in coming versions of Flex and CF), so to the extent you can design your component tier with that in mind, you'll be glad you did.
It's been a while since I wrote CF code, but on the last big project I did with it, I spent a good deal of time designing a functional tier out of CFCs to be used by the plain ol' Web app, much as it sounds like you're doing -- and then later, when it came time to bolt on an Ajax UI for a subsection of the site (it could've been Flex, but in my case, it happened to be a YUI implementation), I created a facade layer of publicly exposed CFCs whose job it was to wrap and expose a specialized subset of the functionality provided by the first tier. Doing so allowed me to leverage and extend existing code in a way unique to the services that needed it, without having to expose the underlying (first tier) CFCs directly.
I'm sure other folks will have many more (and probably more detailed) suggestions, but that's the one big one I have for you first off -- learn, know and use the CF component. Good luck!
I agree with Christian that the best thing you can do is put everything as far as database logic or any other logic for the application in CFC's, and more specifically, I would suggest using webservices. The main reason for this is that it will allow you to eventually have your cf code, which is all of your database persistence and logic on a different server than where you serve the flex applications from, and would allow code reuse for other applications as well. The nice thing too about writing your cfc's as webservices is that you can use them either as webservices or directly as components in Flex using AMF (remote object). Now of course how much those benefits really apply to you depends on your situation, but its a good plan to follow.
But the main suggestion is to think of your application as having a presentation layer and a logic and persistence layer. If you are making a decision, it goes in the logic layer. If you are showing a screen or doing anything with presentation, it goes in that layer. Keeping those things separate will allow you to more easily switch out your presentation layer to flex later on.
Also, it can be useful to trap any errors thrown and return messages as results (with any results, like in a structure) from all methods. Flex has a nasty habit of telling you something went wrong, but not passing along the error information. This will help you to debug and handle any errors that get thrown much easier.
Check out Matt Woodward's presentation on the topic, it's very informative:
And a few general things to add to the answers everyone else provided:
Encapsulate your data interaction in CFCs (typically in Services which delegate to Gateways and DAOs)
In most cases, you'll want to create "bean" CFC's to represent your business objects (users, widgets, etc), these are what will transfer to Flex as ActionScript classes. You'll need to add cfproperty tags to them to make them serializable to ActionScript (case- and order- sensitive!), so pay attention to that when you create them to prevent having to deal with it later, and use one of the code generation tools like the Adobe CF Extensions for Eclipse or Illudium PU36 to do it for you.
Create a remote facade CFC (or set of CFCs depending on how big the app is) that delegates methods to your Services - this is where you set the access for your methods to "remote" - generally the only place you want to do this (it will feel like you're doing a lot of delegating but it pays off to have all your remote services centralized)
As you develop with HTML, treat your remote facade CFCs as your API and make your HTML views as "dumb" as possible. Think of it this way: any logic you write in your CF view will have to be replicated in your Flex view. If you build the project only using your remote API, you'll have a pretty good feel for how Flex will interact with the application.
Check out ColdSpring, it offers a lot of great features for managing all the objects you're going to create!
I don't claim to be an architecture expert and I know I've thrown around a lot of jargon here to keep it short, but some Googling around CF blogs should turn up a lot of info about the design patterns I've mentioned. Good luck!