I want to talk about an interesting scenario I had in code recently. We wanted to change up a connection string based on a flag to any Business Layer method calls being made.
First here’s some facts:
1) We had a base class called DatabaseBase
2) We had a derived class that inherited the base: SomeProjectDB : DatabaseBase
3) Business Layer method calls would eventually use an instance of SomeProjectDB in part to make the associated Data Layer method calls for a BL method
So for example you might have a Business Layer method like so:
1: public Order GetOrder(int id)
2: {
3: Order order = db.GetOrder(id);
4: return order;
5: }
You’d have an instance of db which is an instance of SomeProjectDB.cs created somewhere in code so you can reference and use it.
So then in one of my web services I could have something like this originally before I implement the check:
1: [WebMethod]
2: public Order GetOrder(int id)
3: {
4: MyBusinessLayerNamespace.GetOrder(id);
5: }
Goal: We wanted to use a different connection string than the default if the business layer method calls were being made from a web service (.asmx) like above so that we could make calls using a more secure connection string (one that did not have so many permissions to stuff we really don’t need). Since the alternative connection string would be much more secure than the one we normally are using.
So for any BL method calls we were making in our service methods we are going to use this special connection string. That connection’s SQL user would only have rights to any procs or other resources necessary to run any of the calls that were being made to any BL methods from our web service.
So here’s the base class:
1: public class DatabaseBase
2: {
3: private readonly string connectionString;
4: private bool useCounters;
5:
6: public DatabaseBase(string connectionString)
7: {
8: this.connectionString = connectionString;
9: }
10:
11: ... rest of code
12: }
And for example, here’s SomeProjectDB:
1: public class SomeProjectDB : DatabaseBase
2: {
3: static string defaultConnString = ConfigurationManager.AppSettings["DefaultConnString"];
4:
5: public SomProjectDB() : base(defaultConnString)
6: {
7: }
8:
9: public SomeProjectDB(bool useWebServiceConnection) : base(
10: useWebServiceConnection ? defaultConnectionString :
11: ConfigurationManager.AppSettings["SecureConnectionString"])
12: {
13: }
14:
15: ...rest of code
16: }
Now I can create an instance of this two ways from a Business Layer method:
SomeProjectDB db = new SomeProjectDB();
this would use the default connection string. Since calling the parameterless constructor would end up with the instance of SomeProjectDB passing the local backing field defaultConnString to the base class’s constructor
SomeProjectDB db = new SomeProjectDB(true);
this would call the overloaded constructor that requires useWebServiceConnection. Then I’m passing the incoming useWebServiceConnection value straight to the base class’s constructor and checking whether that value is true to handle which connection string should be used. If it’s set to true, use the special connection string with more security “SecureConnectionString”.
So now, the call in my web service would look like this:
1: [WebMethod]
2: public Order GetOrder(int id)
3: {
4: MyBusinessLayerNamespace.GetOrder(id, true);
5: }
MyBusinessLayerNamespace.GetOrder method would have a new overloaded method that I could use which could take in the true parameter to determine that it should use the secure connection. That BL method would then call db.GetOrder(true) and we’d use that object as part to call the data layer GetOrder method to ensure that DL method is making transactions over that more secure connection string.
Anyway, it’s a lot to think about, thought this was kinda an interesting little problem. This is how I solved it.