Question

In our application data tier we completely rely on stored procedures and web services for Data exchange. We use code like below in loads of pages to execute stored procedures

switch(requesttype)
{    
  case "GetEmployees":
         switch (crud_type)
                 {
                    case "read":
                          Execute Stored Procedure 'A'
                    break;
                 }
   break;      
}

we are looking for ways to remove above code(which is inside class files) to some form of configuration file

  1. We are looking for file storage format that are extremely fast to retrieve(read,parse etc) and save(write,modify etc)

  2. We could implement a security layer above it

  3. Achieve this without much fuss and major changes to existing code.

Was it helpful?

Solution

I think I got ahead of myself. You can't replace code with configuration because the code will do something while a configuration would simply tell the code what or how to do something (unless the configuration itself contains code in which case you've got a paradox). If you want to apply configurability to your code, you'll first need to make it more general/generic (your switch statements indicate that it is not general now). My approach to doing this is described in my original answer (below). It doesn't provide configurability on its own, but could be made to do so (I've done it fairly simply). The code is based on your original question so please readjust your eyes to read it correctly.


The option I've opted for in the past has been to use a factory (whether housed in a Singleton or passed to the function owning your code sample in the form of an IoC container.

Very high level implementation of my approach is basically to define a custom attribute which contains a property that indicates when your type is useful. Something like:

public class DbOperationAttribute : Attribute
{
    public string Operation { get; set; }
}

And a common interface to provide the API needed for your code to be run. Something like:

public interface IDoSomethingSpecial
{
    bool Execute(SomeExecutionContext context);
}

And then you decorate specific classes with the attribute and implement the interface to indicate that they are appropriate for each action:

[DbOperation(Operation = "Read")]
public class DBReadOperation : IDoSomethingUseful
{
    // Our implementation of the `IDoSomethingUseful` interface
    public bool Execute(SomeExecutionContext context)
    {
        // Do something useful in here
    }
}

At some point in your program you will need to be able to discover which types are appropriate for which actions. I do this with reflection, though it could just as easily be done with configuration (which would defeat the point of the attribute). Several IoC containers provide similar discoverability attributes, though using someone else's you'll be left doing things their way (typically).

Once you've discovered which types are appropriate for which actions, you can use something like:

IDoSomethingUseful someAction = myCollectionOfUsefulThings(requesttype);
someAction.Execute(someInstanceOfOurContextType);

Based on this design I would lean towards just using the App.Config/Web.Config to store your configuration. It'll generally be there anyway; may as well use it for your purposes as well.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top