After reading and playing around with the steps mentioned in Scott Mitchell's excellent tutorial on 3-Tier ASP.NET Architecture (the first one is here), coupled with my use of the Web Application Projects addin to VS2005 (found here), I found out a few tips and tricks along the way.
As a summary, the abovementioned series of tutorials discuss steps on how to create the ff:
- A DataAccessLayer (DAL) using a typed/custom DataSet.
- A BusinessLogicLayer (BLL) that's layered on top of the DAL. This is basically a thin wrapper over the DAL.
- A Presentation Layer (PL) using ASP.NET with ObjectDataSource control calling the BLL.
Missing Steps
However, the absence of a web service (or even a remoting) layer to provide a certain degree of indirection and deployment flexibility was sorely missing. This I believe would have fully reflect the more common real-world scenarios that developers using ASP.NET are encountering on a daily basis. Fortunately, it is not that difficult to add one yourself. This is the topic of this post.
Additional Steps
Adding a WebService Layer introduce some new interesting issues, among which are the ff:
1. If a web service layer is introduced, what problem/s then is being addressed by the introduction of this layer?
2. How does the introduction of this layer affect the structure of the application?
3. Does this make the application more brittle to changes?
4. How do you configure the application (or the various components of it) now that it is using a web service layer?
5. Are there certain security requirements that need to be addressed because of this change? If so, how do we do it?
For question 1, I think the main problem being addressed by a web service layer is how to provide some level of indirection between the front end (using ASP.NET pages) and the BLL, with the corresponding advantages:
-- changes to the BLL does not necessarily have to reflect corresponding changes to the application's front end but instead may be handled by the web service. The web service may or may not reflect this changes back to the client ASP.NET pages. The opposite direction is also true: changes to the PL does not require changes to theBLL.
-- this makes it easy to prepare the application for a physical 3-tier deployment. With the original setup of DAL/BLL/PL, deploying the application on more than 1 web or application server machine becomes an issue, since no matter you put the PL components, the DAL and BLL goes along with it. With a web service layer, the PL/WS Proxy components may be placed in a pure web server machine, and the DAL/BLL/WS may be put in an application server. Also with the current setup without the web service layer, it is not very clear how you would call the BLL in one machine from the PL in another machine.
For question 2, the introduction of a web service layer simply needs to be inserted between the PL and the BLL. With this setup, the PL calls the WS which in turns call the BLL which calls the DAL.
For question 3, it does not really make the application more brittle to changes. One effect of the web service layer is that the PL's web reference to the web service, that is the web service proxy, would need to be updated whenever there are changes to the web service. But this is the same steps that needs to be done whether we have a web service layer or not, that is changes to the server application would need to cascade to the client (even if you are using interfaces as a contract between the PL and its server).
For question 4, this is where a bit of playing around produced a small victory for myself. First, since a web service is deployed like a web site, therefore it shares most of the features of a traditional web site, ease of management and security being some of them. Therefore, a normal web service will be accessible by anybody by default. This is because the web service is configured to use Anonymous access in IIS. Therefore to restrict the use of the web service to those users belonging to your trusted list (like users within your company's domain if you're using Active Directory), you need to do 2 things: disable Anonymous access, and enable Integrated Windows Authentication in your web service virtual directory. (This applies to virtual directories for your DAL/BLL/WS solution and the separate PL client project/solution.)
Another step that needs to be done is to add a few settings in your web.config file. Here are the elements that should be added and why:
1. connectionStrings
2. identity = with impersonate attribute set to "true". Note that you need to set this also on the web.config of the PL.
For the connectionStrings element, it is definitely a surprise for me how this one works the way it did. A little bit of explanation is in order why I'm surprised. You see, when you created the DAL project, you might have noticed that the Dataset Designer added an entry in your project's app.config file (not web.config since this is a class library project). This new element is for the connection string to be used by the DataAdapter to connect to the database. Now, when you compile the DAL as a standalone project, it creates an assembly and leaves the app.config as is with the same connectionStrings, which is fine and as expected.
However if your DAL project is part of a solution that's composed of the following separate projects:
- DAL class library project = using app.config, containing the connectionStrings element used to connect to the database
- BLL class library project = using app.config
- WS project = using web.config
you're in for a small surprise: when you compile the Web Service solution, the content of the web.config does not pick up the connectionStrings element from the app.config in the DAL project and yet when you test the web service, it works!
The reason for this is because the DAL picks up the connection string from your <ProjectName>.Properties.Settings.Default.<ConnectionStringName>, which is a dataset designer generated property, which is derived from the ApplicationSettingsBase. The ApplicationSettingsBase, as the name suggests, contains information related to the configuration of your application.
So, "What's the problem with this approach?", you might ask.
The problem arises in this scenario:
- What if you want your Web Service (and therefore your DAL) to call a different database on another machine? This is especially the case when you're done with the development, tested it and now want to deploy the web service to the production servers. Now, since your production database server has a 99% probability of being different from the development database server, you now have a problem: you need to recompile your solution to target this other database server simply because the DAL has a tightly coupled connection to the development database server. So what you do is edit your DAL project, change the database server to connect to and recompile the application. However, although it's a matter of simple change to the DAL, still the problem remains that you can not dynamically change after deployment the database server to connect to.
Or can you?
It turns out you can. All you have to do is copy the connectionStrings element from the app.config of the DAL project to your Web Service project's web.config, before or after deployment, and voila you have a dynamically configured data source! No more recompilation. If you leave this out, the DAL uses its own default connectionStrings element's value created during compilation.
For question 5, I'll create a new blog for this. Wait for it in my new blog.
Subscribe to:
Post Comments (Atom)
What a line of code
I didn't know this line of code (in any language) will make sense but apparently it does: auto l = [](){}; Look at all those bracke...
-
After reading and playing around with the steps mentioned in Scott Mitchell's excellent tutorial on 3-Tier ASP.NET Architecture (the fir...
-
using System; using System.Data; using System.Configuration; using System.Web; using System.Web.Security; using System.Web.UI; using S...
-
I just got a new machine, an Acer laptop with enough bells and whistles to make a developer happy (Core 2 Duo, 2GHZ, 2 GB RAM). As usual I ...
Useful article
ReplyDeleteIts very good... I like it..
ReplyDelete