Skip to content

Software Flexibility in C#

Software Architects have wonderful terms like scalability and flexibility but what do these mean in the real world and how do we start to put these into practice? I would like to start by looking at one of these terms; flexibility.

Software flexibility can mean a lot of things but when it is used to describe a whole system, it normally refers to the ability for the solution to adapt to possible or future changes in its requirements. When you design or build a solution, you should try to cater for these changes which inevitably arrive in the future. This flexibility should be catered for with the design of the system as a whole but there is also no reason not to also include it with the smaller aspects of the system.

The key to building highly flexible systems is the loose coupling of the components. For example, there is no point building a solution that is tightly integrated with active directory if this part could change down the line. This is not something you should do even if you don’t expect it to change in the future. Nothing is cast in stone in software and at some point you will find yourself in a situation where you will wish you had done it differently.

This whole concept of flexibility is probably best explained through an example. In this blog, I will build a small authentication sub-system. Starting with a nasty hard coded piece of code and slowly progressing to a configurable and flexible solution. Feel free to skip to the later steps if the early parts are obvious to you.

Starting out

For the purposes of simplicity, let’s assume that our application is a single threaded application. Threading adds some complexity that will detract from the core of the example. Error handling has also been kept to a minimum (actually, it’s pretty much non-existent) to remove any unnecessary clutter and no exceptions were harmed during the writing of this blog :).

In our example, let’s assume that our active directory implementation has the following; A LogOn method to verify a user name and password, a LogOff method to log the user off the system and a single property LoggedOnUser that returns the name of the user who is logged onto the system. The class would look something like this:

  class TestActiveDirectory
  {
    private string loggedOnUser = "";

    public void LogOff()
    {
      loggedOnUser = "";
    }

    public void LogOn(string userName, string password)
    {
      if ((userName != "ActiveUser") || (password != "password"))
        throw new TestSecurityException("Invalid User Name or Password!");
      loggedOnUser = "ActiveUser";
    }

    public string LoggedOnUser { get { return loggedOnUser; } }
  }

The developer creating the system would be quite impressed with themselves, having created a nice wrapper for all of the active directory logic. They would then start using this new shiny class throughout their application. Pretty soon the application would be riddled with calls to LogOn, LogOff and accesses to LoggedOnUser.

The big problem with this scenario is that eventually there will come a time when this code needs to be changed for a client that does not have active directory installed. Typically what happens then is that a new class is created that is almost identical previous class and a number of “if (…)” blocks are added.

This starts off being the easiest and quickest way to solve the problem but ends up as a maintenance nightmare. The new Oracle authentication class could look like this:

  class TestOracleAuthentication
  {
    private string loggedOnUser = "";

    public void LogOff()
    {
      loggedOnUser = "";
    }

    public void LogOn(string userName, string password)
    {
      if ((userName != "OracleUser") || (password != "password"))
        throw new TestSecurityException("Invalid User Name or Password!");
      loggedOnUser = "OracleUser";
    }

    public string LoggedOnUser { get { return loggedOnUser; } }
  }

Throughout the code we would have nasty unmaintainable titbits like this:

    private void tCheckStatus_Tick(object sender, EventArgs e)
    {
      string userName;
      if (activeDirectorySelected)
        userName = activeDirectory.LoggedOnUser;
      else
        userName = oracleAuthentication.LoggedOnUser;
      if (userName != "")
        statusLabel.Text = "User Name: " + userName;
      else
        statusLabel.Text = "";
    }

As more and more methods and properties are added to the existing authentication classes and new authentication classes are added this quickly descends into chaos.

You can download the code for this part from DependencyInjection_Part_1.zip

Decoupling

So how do we solve this mess? The first step in getting out of this mess is to add an authentication interface. This interface will abstract out the Oracle and Active Directory authenticators from the rest of the application.

So where do we start with the interface? The easiest thing to do is just extract out the common methods and properties (not ideal for interfaces but will do for this example) from the classes and add them to the new interface.

  interface ITestAuthentication
  {
    void LogOff();
    void LogOn(string userName, string password);
    string LoggedOnUser { get; }
  }

The interface should look something like the one above. It’s pretty easy to hook in the new interface to the two classes. The Active Directory class would look like this:

  class TestActiveDirectory : ITestAuthentication
  {
    private string loggedOnUser = "";

    public void LogOff()
    {
      loggedOnUser = "";
    }

    public void LogOn(string userName, string password)
    {
      if ((userName != "ActiveUser") || (password != "password"))
        throw new TestSecurityException("Invalid User Name or Password!");
      loggedOnUser = "ActiveUser";
    }

    public string LoggedOnUser { get { return loggedOnUser; } }
  }

Using the interface in the application is where you see the real differences. The code is much cleaner as all of the “if (…)” blocks are replaced with a single line of code. The interface variable would be declared like this (assuming our system defaults to Active Directory):

    private ITestAuthentication authentication = new TestActiveDirectory();

The code to creating the objects would look like this:

      if (chkActiveDirectory.Checked)
        authentication = new TestActiveDirectory();
      else
        authentication = new TestOracleAuthentication();

And using the interface in the code makes it look a lot cleaner than it previously did.

    private void tCheckStatus_Tick(object sender, EventArgs e)
    {
      string userName;
      userName = authentication.LoggedOnUser;
      if (userName != "")
        statusLabel.Text = "User Name: " + userName;
      else
        statusLabel.Text = "";
    }

All in all we have a much smarter solution for very little work. We have also started the process of breaking up our solution into loosely coupled components.

You can download the code for this part from DependencyInjection_Part_2.zip

Factories

This solution looks, at face value, like we have found the sweet spot, but it falls short in a couple of places. For one, every time we add a new authentication provider we need to rebuild our system. We also need to retest the entire application for each new provider, or at least the parts that interface with our authentication providers. To make matters worse, its not the easiest thing to use these components in other systems. So how do we take this forward? We create a factory. I find that I draw pictures better than I write so I will show a simple class diagram that includes our factory.

Factory

What I have done is start breaking up the components of the authentication system into different libraries; one library for the factory (more about this now), another for the ITestAuthentication interface and additional libraries for each of the authentication providers.

How the factory works is this. We only couple our application to the Authentication Factory and Authentication Interface. At the same time we couple the authentication providers to the Authentication Interfaces but there is no coupling between the application and providers themselves. The authentication providers are registered with the factory after they are loaded and the application asks the factory for the authentication provider by name, when it needs one. It’s important for the factory to be a singleton as both the application and the providers need to access the same instance of the factory class.

This blog is taking the factory a bit further by building a mini plug-in system to dynamically load our provider.

So what does this factory look like?

  public class AuthenticationFactory
  {
    private static readonly AuthenticationFactory instance = new AuthenticationFactory();
    private List<ITestAuthentication> authenticationEngines = new List<ITestAuthentication>();

    // Explicit static constructor to tell C# compiler
    // not to mark type as beforefieldinit
    static AuthenticationFactory()
    {
    }

    private AuthenticationFactory()
    {
    }

    public static AuthenticationFactory Instance
    {
      get { return instance; }
    }

    public void AddAuthenticator(ITestAuthentication authenticator)
    {
      authenticationEngines.Add(authenticator);
    }

    public ITestAuthentication AuthenticatorByType(string authenticationType)
    {
      foreach (var authenticator in authenticationEngines)
      {
        if (authenticator.AuthenticationType == authenticationType)
          return authenticator;
      }
      throw new TestSecurityException("Invalid Authentication Type");
    }
  }

You can ignore some of the code as that code is singleton code. Any robust singleton implementation will do. The important lines are 12, 29-32 and 34-42. These lines are responsible for getting and setting the provider. We put this factory into it’s own library. We also place our ITestAuthentication interface into a library. It’s necessary to add a new property to the authentication interface called AuthenticationType that we will use to give each provider a “Name”. This name is used to retrieve the selected authentication provider. This gives us a way of configuring the system through XML or another configuration system in the future.

We create a separate DLL for each provider and each of these providers references the interface library. We implement the new interface property in each of these providers and can then build them.

We add the following method to our main application so that it can dynamically load each of the authentication providers.

    void LoadLibrary(string libraryName)
    {
      Assembly loadedLibrary;
      loadedLibrary = Assembly.LoadFrom(libraryName);
      foreach (Type selectedType in loadedLibrary.GetTypes())
      {
        bool isAuthenticator = selectedType.GetInterfaces().Any(x => x == typeof(ITestAuthentication));
        if (isAuthenticator)
        {
          var instance = (ITestAuthentication) Activator.CreateInstance(selectedType);
          AuthenticationFactory.Instance.AddAuthenticator(instance);
        }
      }
    }

This block of code loads the library by its library (dll) name and then iterates through all of the types in the library to see if there are any that implement our authentication interface. If it finds one, it registers that type with the factory.

Lastly, we need to tell our application to load the two libraries by including a couple of calls to LoadLibrary. The last line of code sets our default authentication provider to the Active Directory one.

    public Form1()
    {
      InitializeComponent();
      LoadLibrary("ActiveDirectoryLibrary.dll");
      LoadLibrary("OracleAuthenticationLibrary.dll");
      authentication = AuthenticationFactory.Instance.AuthenticatorByType("ActiveDirectory");
    }

Accessing one of the authentication providers is as easy as calling a method on the factory and giving it the name of the authentication provider (AuthenticationType). For the Active Directory one it looks like this:

        authentication = AuthenticationFactory.Instance.AuthenticatorByType("ActiveDirectory");

and for the Oracle one it looks like this:

        authentication = AuthenticationFactory.Instance.AuthenticatorByType("Oracle");

At this point, it would probably be a good idea to open the project and look at the code. This type of solution adds significant flexibility to our previous effort. Yes there is a bit more code, but we are slowly starting to arrive at that word “flexible”. No longer is our application tied to the providers. We can happily build a brand new authentication provider and not even rebuild our application (if our configuration is working the way it should). Taking it a step forward, we also now have a solution where we can create a set of test packs for our providers and individually test and certify them. Any provider that passes the tests should work properly with our application(s). I have cheated in this example to make it easier for people to test the code. I have referenced the Active Directory and Oracle Authentication providers from the main application. This is not necessary and should not be done when using this approach in a real world situation but it will ensure that the DLL’s get copied to the application folder which we need to run the application.

You can download the code for this part from DependencyInjection_Part_3.zip

The next step

Where do we go to from here? It looks like we have the ideal solution. It’s not; there are still some enhancements that we can make to the existing solution. The big problem with this approach is that we are still duplicating code and there is more coupling than there needs to be. For every different provider type (authenticator, configuration adapter, etc.) we have another factory. There is also the problem that your application needs to know about two things, the authentication interface and the authentication factory. What would need to change if we switched from a single authenticator instance to a pool of authenticators to cater for threading? We would have to make some fairly big changes to our factory and also make some changes to the providers and the core application.

Wouldn’t it be nice to have a generic solution where we only need to create the interface? Think of it as a big all-purpose factory. But not just a factory, it’s a solution that caters for singletons, pools and pretty much any type of implementation that you would like. That’s where dependency injection comes in.

With dependency injection, an application will request a service or component from the dependency injection container and the container will be responsible for loading and configuring the requested service.

Looking at the existing example, what if I wanted to have a number of connections to the authentication provider at the same time? I would need to pull out the hammer and make a few modifications to my factory. Rather than do that, I will start with a new version, one that makes use of Dependency Injection.

The code that follows from this point onwards uses the Spring Framework. I have included the library in the example but I would advise you to download the full package and take a look. You can download it from http://www.springframework.net/. There are a number of dependency injection frameworks out there (such as Ninject) but I like the configuration system in Spring.NET.

So what do we need to switch across to Dependency Injection and the Spring.NET Framework? Well, the changes are actually quite minimal from our factory solution. First, we make a couple of boilerplate changes.

1) We remove the reference to our factory from the main application as it is no longer needed.

2) We need to add the Spring.Core and Common.Logging libraries to our references in our host application.

3) We add an app.config file to our host application that includes the configuration information for the spring framework regarding logging and our objects.

      <o name="ActiveDirectory" type="ActiveDirectoryLibrary.TestActiveDirectory, ActiveDirectoryLibrary">
      </o>
      <o name="Oracle" type="OracleAuthenticationLibrary.TestOracleAuthentication, OracleAuthenticationLibrary">
      </o>

I had to unfortunately change the name of the tags from “object” to “o” to get past WordPress. These two lines of code tell the spring framework about our authentication providers.

4) Lastly, we need to add a few lines of code to our application. We create a reference to the Context like this:

    IApplicationContext ctx = ContextRegistry.GetContext();

And we are then able to retrieve the authentication provider like this:

      authentication = (ITestAuthentication)ctx.GetObject("ActiveDirectory");

That’s it; our application is now using dependency injection. “ActiveDirectory” is the name of the provider as specified in the app.config file. As before, I have included unnecessary references to the two authentication providers to make sure the files are copied to the application folder.

You can download the code for this part from DependencyInjection_Part_4.zip

But wait, there’s more :).

If you remember above, I mentioned something about changing the lifespan of the classes (Singleton, etc.). In my example, let’s say that our interface to Oracle would only work as a single connection. All we would need to do is add the singleton=”true” attribute in the configuration. The framework will do the rest.

  <o name="Oracle" type="OracleAuthenticationLibrary.TestOracleAuthentication, OracleAuthenticationLibrary" singleton="true">
  </o>

So, what is the point of my last weak attempt at humour? The point is that switching to this sort of framework gives you far more flexibility in your solution and that’s what this blog is ultimately about. You can also do things like property injection. This lets us change properties through the xml configuration file. I added a new authentication type in this last step called a Dynamic Authentication Provider. This new provider is just a proxy onto one of the original two providers but it gets the name of this provider set through property injection. The provider code looks like this:

  class DynamicAuthentication : ITestAuthentication
  {
    private ITestAuthentication hostedAuthentication;

    public ITestAuthentication HostedAuthentication
    {
      get
      {
        return hostedAuthentication;
      }
      set
      {
        hostedAuthentication = value;
      }
    }

    public void LogOff()
    {
      hostedAuthentication.LogOff();
    }

    public void LogOn(string userName, string password)
    {
      hostedAuthentication.LogOn(userName, password);
    }

    public string LoggedOnUser { get { return hostedAuthentication.LoggedOnUser; } }

    public string AuthenticationType { get { return "Dynamic"; } }
  }

As you can see, it includes a new property called HostedAuthentication. This property is set through the app.config file like this:

  <o id="Dynamic" type="DependencyInjection_Part_5.DynamicAuthentication, DependencyInjection_Part_5">
    <property name="HostedAuthentication" ref="ActiveDirectory"/>
  </o>

So, by changing a single line of configuration xml, I can switch on Singleton’s or switch providers all together.

You can download the code for this part from DependencyInjection_Part_5.zip. The last download includes the source code for all of the projects.

More Information on Dependency Injection

There is a lot more to Dependency Injection than what I have covered in this blog. Constructor, Property, Method and Field injection are all valid forms of Injection. I also haven’t gone into the details of how it’s accomplished but rather just shown a glimpse of it. I would suggest doing some googling on the subject if you find it interesting.

Interface Design

Before I finish, there are a couple of important aspects of interface design that I should mention. The temptation is always there to take all of the methods and properties from a class and slap them in an interface. This will not necessarily solve the tight coupling problem. Why is this? Often people take functionality that is specific to a provider and add this to their interface. All that does is restrict your application to only use the provider in question.

For example, let’s say that Active Directory in our example above includes a neat function to send a user a sms when they log on. Including this SendSmsToUser option in our interface and application will pretty much force us to use Active Directory until we can mimic the behaviour in the other providers.

There are three approaches you can take to defining your interfaces:

1) The first is to look at the lowest common denominator and create an interface around that.

2) Secondly, you can try and create interfaces that include all of the functionality that you would like to use and then use some attributes or a function to tell the application which functionality is supported.

3) Finally, you can try and find a balance between the previous two. Use the lowest common denominator and add some of the more advanced functionality as optional features.

You can make use of multiple interfaces to cover the functionality. Think carefully when creating interfaces. These should be seen as a contract that you don’t break very easily.

Summary

In summary, things have definitely changed over time. In the old days, people used to clutter their code with “if (x) y;” statements, trying to cover all of the bases. A lot of modern systems use factories to provide a level of abstraction and the trend is now towards dependency injection.

Think flexibility when you design the solution and you will definitely arrive at a better solution.

This is the C# version of one of my previous blogs. It’s been on the cards for a while; I just didn’t make the time to complete it until now.

Oracle Tips and Tricks

While I generally prefer to build solutions that are database agnostic, sometimes it’s necessary to move some code into stored procedures or triggers in the interests of performance. This reduces the interaction between the application and the database but also gives the database more control over optimizations. This blog is about some small tricks that you can do in Oracle. I will follow up with a later one on SQL Server tips.

Joining onto or querying Cursors

Cursors are both a blessing and a curse. They provide a lot of flexibility but one part where they really fall short is when you want to join against them with a query or extract a single row out of the cursor using a query. They don’t work that way so you end up scratching your head. Well, there are a few ways around it. The quickest (not so quick from Oracle’s perspective but rather from a development standpoint) and dirtiest way to get this working is to use the Oracle XML operations to convert it to an xml table.

Let’s assume that you have a cursor with the following fields:

Client varchar2(100)
Invoice_Number Number(16)
Amount Number(16,2)

The idea is to get all of the data into a “table” that we can use for joins or queries. The trick is to do something like the following:

select I.*
  from xmltable('/ROWSET/ROW' passing xmltype(MyCursor) columns
    Client varchar2(100) path 'Client',
    Invoice_Number Number(16) path 'Invoice_Number',
    Amount Number(16,2) path 'Amount') I;

I wouldn’t use this for large cursors or for operations that require really high performance but it’s really useful to use on the odd occasion. Here is a full set of code to test it out:

-- Create the test table
CREATE TABLE TestInvoiceTable
(
Client varchar2(100),
Invoice_Number Number(16),
Amount Number(16,2)
);

-- Add some test data
INSERT INTO TestInvoiceTable (Client, Invoice_Number, Amount) VALUES ('Client A', 1231, 55.50);
INSERT INTO TestInvoiceTable (Client, Invoice_Number, Amount) VALUES ('Client B', 1232, 122.96);
INSERT INTO TestInvoiceTable (Client, Invoice_Number, Amount) VALUES ('Client A', 1233, 232.00);
INSERT INTO TestInvoiceTable (Client, Invoice_Number, Amount) VALUES ('Client C', 1234, 85.14);

-- A Block of code to test our query
declare
  example_cursor SYS_REFCURSOR;
  ExtractInvNo Number(16);
Begin
  -- Build a dummy cursor
  OPEN example_cursor FOR
  SELECT * FROM TestInvoiceTable;

  -- Use the cursor in a traditional query
  SELECT I.Invoice_Number INTO ExtractInvNo
  FROM XMLTABLE('/ROWSET/ROW' PASSING XMLTYPE(example_cursor) COLUMNS
    Client varchar2(100) path 'CLIENT',
    Invoice_Number Number(16) path 'INVOICE_NUMBER',
    Amount Number(16,2) path 'AMOUNT') I WHERE I.Amount > 100 AND ROWNUM = 1;

  -- Output the value
  DBMS_OUTPUT.PUT_LINE(ExtractInvNo);
end;

This will output 1232 to the output window.

Finding Blockers

This can be done really quickly by querying the v$session_blockers table. It will quickly return which sessions are being blocked and by who. Not very difficult to find but it certainly helps if you find your oracle session just hanging.

select * from v$session_blockers

Running Totals in a Query

Getting a running total can be really useful in queries. We may want to find out how many line items on an invoice are still outstanding if we have only received part of the payment on that invoice or we may just want to have a carrying value for a report. Oracle has a way to do this. We can even have a running total for a particular subset of our data. So, using the table that I added earlier, we could do something like this:

SELECT Client, Invoice_Number, Amount,
  SUM(Amount) OVER 
    (ORDER BY Client, Invoice_Number) AS Running_Total,
  SUM(Amount) OVER 
    (PARTITION BY Client ORDER BY Client, Invoice_Number) AS Client_Total
FROM TestInvoiceTable ORDER BY Client, Invoice_Number

This will return the following data:

CLIENT INV_NUMBER AMOUNT RUNNING_TOTAL CLIENT_TOTAL
Client A 1231 55.50 55.5 55.5
Client A 1233 232.00 287.5 287.5
Client B 1232 122.96 410.46 122.96
Client C 1234 85.14 495.6 85.14

As you can see, we have two running totals. The running total for the whole query; and the running total for each client courtesy of PARTITION BY.

Conclusion

Databases might not be your cup of tea but it helps to know what you can do with them. A few tricks can go a long way to making your life easier and ultimately improving the performance and robustness of your solution.

Don’t forget the ‘How’

We all know that software projects have a bad name in the industry. Very often these projects are late and don’t really deliver to the clients expectations. There have been lots of ways that companies have tried to address this such as running projects using agile methodologies, etc. This post is slightly different. It’s about addressing these problems by trying to understand the client a bit better.

Business Analysts will visit the client and document, in detail, what work the client needs done. The business objects, business rules, etc. are all carefully collated and pushed down the chain until they arrive at the developers. However, there is often a problem lurking in the background. How the client will be using the system is often missed or forgotten. Developers are experts at thinking in technical terms. They will take the business objects and quickly draw up a few database tables. From those, they already start picturing the visual parts of the system in their minds. At this point, things could already be going very wrong. That crucial piece of information on how the users work or would like to work could be missing.

Lets say that we were building a system to manage a fleet of vehicles, there is a big difference between capturing a single vehicle and having to capture 50 or 100 of them. That’s where the understanding of how the users will be using the system starts to become very important. Capturing a large number of vehicles brings other complications that effect everything from the back-end database right the way through to the user interface. We may need to have a holding table to store the vehicles while they are being captured. If we don’t start building it properly from the word go then we could end up with a lot of rework and wastage.

What I found really helps is for developers to try and put themselves in the users place for a while and try and understand not just what the users do, but how they do it as well.

Software Flexibility

Software Architects have wonderful terms like scalability and flexibility but what do these mean in the real world and how do we start to put these into practice. I would like to start by looking at one of these terms; flexibility.

Software flexibility can mean a lot of things but when it is used to describe a whole system, it normally refers to the ability for the solution to adapt to possible or future changes in its requirements. When you design or build a solution you should try to cater for these changes which inevitably arrive in the future. This flexibility should be catered for with the design of the system as a whole but there is also no reason not to also include it with the smaller aspects of the system.

The key to building highly flexible systems is the loose coupling of its components. For example, there is no point building a solution that is tightly integrated with active directory if this part could change down the line. This is not something you should do even if you don’t expect it to change in the future. Nothing is cast in stone in software and at some point you will find yourself in a situation where you will wish you had done it differently.

This whole concept of flexibility is probably best explained through an example. In this blog I will build a small authentication sub-system. Starting with a nasty hard coded piece of code and slowly progressing to a configurable and flexible solution. Feel free to skip to the later steps if the early parts are obvious to you.

Starting out

For the purposes of simplicity, let’s assume that our application is a single threaded application. Threading adds some complexity that will detract from the core of the example. Error handling has also been kept to a minimum (actually, it’s pretty much non-existent) to remove any unnecessary clutter and no exceptions were harmed during the writing of this blog :).

In our example, let’s assume that our active directory implementation has the following; A LogOn method to verify a user name and password, a LogOff method to log the user off the system and a single property LoggedOnUser that returns the name of the user who is logged onto the system. The definition would look something like this.

  TtstActiveDirectoryAuthentication = class(TObject)
  private
    // ...
    FLoggedOn: Boolean;
    function GetLoggedOnUser: string;
    // ...
  public
    procedure AfterConstruction; override;
    procedure LogOff;
    procedure LogOn(AUserName: string; APassword: string);
    property LoggedOnUser: string read GetLoggedOnUser;
  end;

The developer creating the system would be quite impressed with themselves, having created a nice wrapper for all of the active directory logic. They would then start using this new shiny class throughout their application. Pretty soon the application would be riddled with calls to LogOn, LogOff and accesses to LoggedOnUser.

The big problem with this scenario is that eventually there will come a time when this code needs to be changed for a client that does not have active directory installed. Typically what happens then is that a new class is created that is almost identical previous class and a number of “if … then …” blocks are added.

This starts off being the easiest and quickest way to solve the problem but ends up as a maintenance nightmare. The new Oracle authentication class could look like this:

  TtstOracleAuthentication = class(TObject)
  private
    // ...
    FLoggedOn: Boolean;
    function GetLoggedOnUser: string;
    // ...
  public
    procedure AfterConstruction; override;
    procedure LogOff;
    procedure LogOn(AUserName: string; APassword: string);
    property LoggedOnUser: string read GetLoggedOnUser;
  end;

Throughout the code we would have nasty unmaintainable titbits like this:

procedure TfrmMiniApp.tSetUserNameTimer(Sender: TObject);
var
  _UserName: string;
begin
  if FActiveDirectory then
    _UserName := FtstActiveDirectoryAuthentication.LoggedOnUser
  else
    _UserName := FtstOracleAuthentication.LoggedOnUser;
  if _UserName <> '' then
    sbFooter.Panels[0].Text := 'User Name: '+_UserName
  else
    sbFooter.Panels[0].Text := '';
end;

As more and more methods and properties are added to the existing authentication classes and new authentication classes are added this quickly descends into chaos.

You can download the code for this part from Pass1.zip

Decoupling

So how do we solve this mess? The first step in getting out of this mess is to add an authentication interface. This interface will abstract out the Oracle and Active Directory authenticators from the rest of the application.

So where do we start with the interface? The easiest thing to do is just extract out the common methods and properties (not ideal for interfaces but will do for this example) from the classes and add them to the new interface.

  ItstAuthentication = interface(IInterface)
    ['{2ACA6F5F-4BD9-4C69-BB59-2C6502AF822B}']
    function GetLoggedOnUser: string;
    procedure LogOff;
    procedure LogOn(AUserName: string; APassword: string);
    property LoggedOnUser: string read GetLoggedOnUser;
  end;

The interface should look something like the one above. It’s pretty easy to hook in the new interface to the two classes. The Active Directory class would look like this:

  TtstActiveDirectoryAuthentication = class(TInterfacedObject, ItstAuthentication)
  private
    // ...
    FLoggedOn: Boolean;
    function GetLoggedOnUser: string;
    // ...
  public
    procedure AfterConstruction; override;
    procedure LogOff;
    procedure LogOn(AUserName: string; APassword: string);
    property LoggedOnUser: string read GetLoggedOnUser;
  end;

Using the interface in the application is where you see the real differences. The code is much cleaner as all of the “if … then …” blocks are replaced with a single line of code. The interface variable would be declared like this.

  private
    { Private declarations }
    FtstAuthentication: ItstAuthentication;

The code to creating the objects would look like this:

  if chkActiveDirectory.Checked then
    FtstAuthentication := TtstActiveDirectoryAuthentication.Create
  else
    FtstAuthentication := TtstOracleAuthentication.Create;

And using the interface in the code looks a lot cleaner than it previously did.

procedure TfrmMiniApp.tSetUserNameTimer(Sender: TObject);
var
  _UserName: string;
begin
  _UserName := FtstAuthentication.LoggedOnUser;
  if _UserName <> '' then
    sbFooter.Panels[0].Text := 'User Name: '+_UserName
  else
    sbFooter.Panels[0].Text := '';
end;

All in all we have a much smarter solution for very little work. We have also started the process of breaking up our solution into loosely coupled components.

You can download the code for this part from Pass2.zip

Factories

This solution looks, at face value, like we have found the sweet spot but it falls short in a couple of places. For one, every time we add a new authentication provider we need to rebuild our system. We also need to retest the entire application for each new provider, or at least the parts that interface with our authentication providers. It’s also not the easiest thing to use these components in other systems. So how do we take this forward? We create a factory. I find that I draw pictures better than I write so I will show a simple class diagram that includes our factory.

What I have done is start breaking up the components of the authentication system into different libraries. One library for the factory (more about this now) and the ItstAuthentication interface and additional libraries for each of the authentication providers.

How the factory works is this. We only couple our application to the Authentication Factory and Authentication Interface. At the same time we also couple the authentication providers to the Authentication Factory and Authentication Interface but there is no coupling between the application and providers themselves. The authentication providers register themselves with the factory then they are first loaded and the application asks the factory for the active authentication provider. It’s important for the factory to be a singleton as both the application and the providers need to access the same instance of the factory class.

This blog is taking the factory a bit further by building a mini plug-in system to dynamically load our provider.

So what does this factory look like?

  TtstAuthenticationFactory = class(TObject)
  private
    FActiveAuthenticator: ItstAuthentication;
  protected
    constructor CreateInstance;
    class function AccessInstance(Request: Integer): TtstAuthenticationFactory;
  public
    constructor Create;
    destructor Destroy; override;
    class function Instance: TtstAuthenticationFactory;
    class procedure ReleaseInstance;
    procedure SetActiveAuthenticator(AAuthenticator: ItstAuthentication);
    property ActiveAuthenticator: ItstAuthentication read FActiveAuthenticator;
  end;

You can ignore the majority of the code as that code is singleton code added by ModelMaker. Any robust singleton implementation will do. The important lines are 12, 21 and 22. These lines are responsible for getting and setting the provider. We put this factory along with the authentication interface into a BPL package.

We create a DLL for each provider. It’s important to make sure that you compile the DLL with runtime packages enabled and set the package list to contain our factory package. We also add the factory and interface unit names to the uses clause.

At the end of each unit where our provider is declared we add a line to automatically create an instance of the provider and set it as the active authenticator. This is done by using the following line of code.

begin
  TtstAuthenticationFactory.Instance.SetActiveAuthenticator(
    TtstActiveDirectoryAuthentication.Create);
end.

We add the next couple of lines of code to our main application to load the authenticator that we would like to use (normally the authenticator would be provided by configuration data) and then get the active authenticator from the authentication factory.

begin
  LoadLibrary(PChar('ActiveDirectory\ActiveDirectoryAuthentication.dll'));
  FtstAuthentication := TtstAuthenticationFactory.Instance.ActiveAuthenticator;
end;

You also need to make the same package changes to the host application. Enable runtime packages and set the package list to contain our factory package. Why is all of this necessary? Because it ensures that both the host application and the provider access the same factory. Without it, they will both have their own singleton of the factory in different memory spaces and as they say, “and never the twain shall meet”.

At this point it would probably be a good idea to open the project and look at the code. This type of solution adds significant flexibility to our previous effort. Yes there is a bit more code, but we are slowly starting to arrive at that word “flexible”. No longer is our application tied to the providers. We can happily build a brand new authentication provider and not even rebuild our application (if our configuration is working the way it should). Taking it a step forward, we also now have a solution where we can create a set of test packs for our providers and individually test and certify them. Any provider that passes the tests should work properly with our application(s).

You can download the code for this part from Pass3.zip

The next step

Where do we go to from here? It looks like we have the ideal solution and for users of Delphi who are still working with Delphi versions older than Delphi 2010 it probably is. There are some enhancements that we can make to the existing solution. We can get the factory to create the adapter instead of the provider itself and other tweaks but not much more than that.

The big problem with this approach is that we are still duplicating code and there is more coupling than there needs to be. For every different provider type (authenticator, configuration adapter, etc) we have another factory. There is also the problem that both your application and providers need to know about two things, the authentication interface and the authentication factory. What would need to change if we switched from a single authenticator instance to a pool of authenticators to cater for threading? We would have to make some fairly big changes to our factory and also make some changes to the providers and the core application.

Wouldn’t it be nice to have a generic solution where we only need to create the interface? Think of it as a big all-purpose factory. But not just a factory; it’s a solution that caters for singletons, pools and pretty much any type of implementation that you would like. That’s where dependency injection comes in.

With dependency injection, an application will request a service or component from the dependency injection container and the container will be responsible for loading and configuring the requested service.

Looking at the existing example, what if I wanted to support both Active Directory and Oracle Authentication at the same time? I would need to pull out the hammer and make a few modifications to my factory. Rather than do that I will start with a new version, one that makes use of Dependency Injection.

To compile any code from this point onwards, you will need to download the Delphi Spring Framework from http://code.google.com/p/delphi-spring-framework/.

So what do we need to switch across to Dependency Injection and the Delphi Spring Framework? Well, the changes are actually quite minimal. First we make a couple of boilerplate changes.

1) We need to delete our factory from the authentication package as it is no longer needed.

2) We need to add the spring framework packages to the runtime packages list by adding the following two packages “Spring.Core;Spring.System”. This should be done to the providers and the host application.

3) We add the Spring.Container unit to the uses clause of our providers and the Spring, Spring.Container, Spring.Services units to the uses clause of our host application.

We change the code at the end of each unit where our provider is declared to now register our providers (services) with the global spring container instead of our factory.

begin
  GlobalContainer.RegisterComponent<TtstActiveDirectoryAuthentication>.
    Implements<ItstAuthentication>('ActiveDirectory');
end.

This registers the provider (TtstActiveDirectoryAuthentication) with the container and tells it that the provider implements the ItstAuthentication interface. We also give it a friendly name (yes, I know that I have hardcoded the name :)) so that we can load the class through a string in the future. This is very important because it lets us add our providers as configuration data.

All we need to do now is change the way that we retrieve our class. Instead of using the factory, we now ask the spring singleton ServiceLocator to retrieve our class based on the friendly name. We still need to load the library as we did before, except in this case, we can load both libraries. We also need to call the build method which instructs the container to inspect all of the meta-data.

begin
  LoadLibrary('ActiveDirectory\ActiveDirectoryAuthentication.dll');
  LoadLibrary('Oracle\OracleAuthentication.dll');
  GlobalContainer.Build;
  FtstAuthentication := ServiceLocator.GetService<ItstAuthentication>('Oracle');
end;

That’s it; our application can now pick the authentication provider it would like to use by just specifying the friendly name to the service locator.

But wait, there’s more :)

If you remember above I mentioned something about changing the lifespan of the classes (Singleton, etc.). In my example, let’s say that our interface to Oracle would only work as a single connection. All we would need to do is add the [Singleton] attribute before the class. The framework will do the rest.

type
  [Singleton]
  TtstOracleAuthentication = class(TInterfacedObject, ItstAuthentication)
  private
    // ...
    FLoggedOn: Boolean;

So what is the point of my last weak attempt at humour? The point is that switching to this sort of framework gives you far more flexibility in your solution and that’s what this blog is ultimately about.

You can download the code for this part from Pass4.zip

More Information on Dependency Injection with Delphi

There is a lot more to Dependency Injection than what I have covered in this blog. Constructor, Property, Method and Field injection are all valid forms of Injection. If you want some more information on Dependency Injection with the Spring Framework in Delphi, hop over to Nick’s blog at http://www.nickhodges.com/.

Interface Design

Before I finish there are a couple of important aspects of interface design that I should mention. The temptation is always there to take all of the methods and properties from a class and slap them in an interface. This will not necessarily solve the tight coupling problem. Why is this? Often people take functionality that is specific to a provider and add this to their interface. All that does is restrict your application to only use the provider in question.

For example, let’s say that Active Directory in our example above includes a neat function to send a user a sms when they log on. Including this SendSmsToUser option in our interface and application will pretty much force us to use Active Directory until we can mimic the behaviour in the other providers.

There are three approaches you can take to defining your interfaces.

1) The first is to look at the lowest common denominator and create an interface around that.

2) Secondly, you can try and create interfaces that include all of the functionality that you would like to use and then use some attributes or a function to tell the application which functionality is supported.

3) Finally, you can try and find a balance between the previous two. Use the lowest common denominator and add some of the more advanced functionality as optional features.

You can make use of multiple interfaces to cover the functionality. Think carefully when creating interfaces. These should be seen as a contract that you don’t break very easily.

Interfaces in Delphi

No blog that includes Delphi and interfaces would be complete without a word of warning. Interfaces in Delphi are, by default, reference counted. When there are no more variables pointing to the interface, the object will be destroyed. What that means is that you should never mix interfaces and object pointers. Doing so is risky and likely to end up with access violations.

Summary

In summary, things have definitely changed over time. In the old days, people used to clutter their code with “if x then y” statements, trying to cover all of the bases. A lot of modern systems use factories to provide a level of abstraction and the trend is now towards dependency injection.

Think flexibility when you design the solution and you will definitely come out with a better solution.

Thinking Outside the Box

Developers almost always follow the most logical approach when trying to solve a problem. This is a good trait but sometimes it produces a suboptimal solution. One such case can be found in a typical security system.

The Problem

Let me start by painting the scenario. We have a security solution where our users and groups come from active directory and we hold the permissions associated with those entities in a local database (Oracle, SQL Server, etc).

Our Security System

Every time we logon, we need to get a list of groups that the user belongs to and then use this list of groups in all of our permission checks to see whether or not the user has permission to access a specific object or UI element.

To illustrate this scenario, I will use an example where we have a user (our Development Manager) that belongs to 3 groups, Managers, Developers and DBA’s. When this user logs into active directory our software will receive this list of 3 groups for him.

User Hierarchy

While solving the solution, we would normally go through a couple of iterations. This blog entry will follow that process.

The Brute Force Solution (First Pass)

In this solution, our database consists of a single table with the group ID, the objects and whether or not we have permission to access the object. In this approach, we simply iterate through all of the ID’s and query the database to get the various permissions. These are then consolidated together. Extending our example from above, we could have a permission table that looks something like this:

Permission Table

Every time we need to check permissions for our user above, we would need to run 3 queries against the database.

SELECT Permission FROM PermissionTable WHERE
Object = ‘Object 1’ AND Entity = ‘Group 1’
SELECT Permission FROM PermissionTable WHERE 
Object = ‘Object 1’ AND Entity = ‘Group 2’
SELECT Permission FROM PermissionTable WHERE 
Object = ‘Object 1’ AND Entity = ‘Group 3’

We could stop the moment we receive a ‘Deny’ permission as this would prevent access regardless of the remaining results, but you get the idea. This is obviously not an optimal solution.

While very few developers will end up going this route, I have included it so that those new to software development will understand the process that developers normally go through while working towards a solution.

A User/Group Table (Second Pass)

This is the solution that most developers end up with. With this solution, our database consists of a two tables. The first one is the same one we used previously with the group ID, the objects and whether or not we have permission to access the object. The second is a table that contains the relationships between our users and the groups that they are linked to.

For this approach, things get a little more complicated. When a user first logs on, we need to perform the following actions:

  1. Delete all rows from the User/Groups table that contain a reference to our user.
  2. Add entries for each of the groups to the User/Group table.

After that, it’s plain sailing and we can join against this table and perform a single query to get the results for our permission check. It does not make sense to search the table first as we would have to check each and every group to make sure that the user still belongs to these groups.

Again going back to our example above, we would have the following as our two tables.

User/Group Permissions

When our user first logs in we would perform the following 4 queries:

DELETE FROM UserGroups WHERE User = ‘User 1’
INSERT INTO UserGroups (User, Group) 
VALUES (‘User 1’,‘Group 1’)
INSERT INTO UserGroups (User, Group) 
VALUES (‘User 1’,‘Group 2’)
INSERT INTO UserGroups (User, Group) 
VALUES (‘User 1’,‘Group 3’)

We could get our list of permissions back from the DB with a query that would look something like this:

SELECT Permission FROM PermissionTable WHERE 
Object = ‘Object 1’ AND Group IN 
(SELECT Group from UserGroups WHERE User = ‘User 1’)

This can be optimised to return a simple True/False including the Deny permissions.

This is normally where things stop. We have a fairly good solution that does the job but it has a few flaws:

  1. There is a fair amount of work required every time the person logs onto the system and we constantly delete and then re-add entries to the User/Groups table, even when there are no changes.
  2. We don’t have an easy way to update these relationships once the person is logged in. We would have to go through our full logon procedure every time.
  3. Very often a number of people will belong to the same set of groups. In this solution, every user who has the same user/group relationships would receive a duplicate set of entries in the user/groups table with the only difference being their user id.

The Elegant Solution (Third Pass)

This brings me to what I call the elegant solution. This solution focuses on trying to limit the database interactions and updates so that our user’s relationships can be updated on the fly as and when they are required.

As with the previous solution, our database consists of a two tables. The first one is the same one we used in both cases previously with the group ID, the objects and whether we have permission to access the object or not. The second is a table that contains the relationships with our groups. The big difference here is that we don’t use the user ID in our relationship table but rather use a hash. This hash is calculated by sorting all of the groups, appending them together and then performing an MD5/SHA hash on the resulting text.

Our actions are similar to the previous pass when the users first log in but we are now able to check whether our group set is already in the database. We would go through the following actions at logon:

  1. Sort and Hash Groups.
  2. Search database for our hash. If the hash is missing then add entries for each of the groups to the Hash/Group table.

From this point onwards, we just use our hash instead of the user ID in the queries and as before, we can join against this table and perform a single query to get the results for our permission check.

With our example from above, we would have the following as our two tables.

Hash/Group Permissions

When our user logs in we would perform a query similar to the one below to check if we have already added this combination:

SELECT COUNT(*) FROM HashGroups where 
Hash = ‘04ce9deac2717a4f230cdab2e82eba3b’

Depending on the outcome, it may be necessary to add our groups but this would only happen the first time a user logged in with our group combination. For subsequent users logging in with the same groups, we would find that the hash already exists and skip this step.

INSERT INTO HashGroups (Hash, Group) 
VALUES (‘04ce9deac2717a4f230cdab2e82eba3b’,‘Group 1’)
INSERT INTO HashGroups (Hash, Group) 
VALUES (‘04ce9deac2717a4f230cdab2e82eba3b’,‘Group 2’)
INSERT INTO HashGroups (Hash, Group) 
VALUES (‘04ce9deac2717a4f230cdab2e82eba3b’,‘Group 3’)

Getting the list of permissions back from the DB with a query would also be pretty simple and would look something like this:

SELECT Permission FROM PermissionTable WHERE 
Object = ‘Object 1’ AND Group IN 
(SELECT Group from HashGroups WHERE 
Hash = ‘04ce9deac2717a4f230cdab2e82eba3b’)

This can be optimised to return a simple True/False including the Deny permissions.

We could periodically check for updates to the users groups and then recalculate the hash and go through the logon process again. You could also enhance the security of the solution by including some extra information in the hash such as the first character from the first 5 groups.

This approach would also work well for a scenario where you have a security system with internal authentication and hierarchical roles.

Follow

Get every new post delivered to your Inbox.