Your intuition is pretty good in that your classes are indeed very tightly coupled to one another. I'm going to be referencing Bob Martin's Principles of Object Oriented Design.
Following the Single Responsibility Principle, you want to make sure that you don't have to update both of these classes if one of them changes. Right now both classes know a little too much about each other.
We can start with EditMapUtilites
and refactor access to the session handler to more accurately convey the intent. Mainly, application state scoped to the user. Also, we can change how we access those values to make it less coupled by using methods that accomplish the same goal.
public class EditMapUtlities
{
//Omitting the wireup details for now
private SessionHandler ApplicationState {get; set;}
public static Boolean isInitialEditMapPageLoad
{
get { return ApplicationState.GetValue<Boolean>("EditMapInitialPageLoad"); }
set { ApplicationState.SetValue("EditMapInitialPageLoad", value); }
}
// REST OF CLASS NOT GERMAIN TO DISCUSSION AND OMITTED
}
And the SessionHandler
class would now contain two new methods:
public static T GetValue<T>(String key)
{
return currentSession[key] ?? default(T);
}
public static void SetValue(String key, Object val)
{
currentSession[key] = val;
}
Ok, so one class is now slightly more verbose, but your session class is simpler and more flexible. Adding additional values is simple, but you may ask yourself why not just use straight session?
The reason we restructured the classes this way was to get us one step closer to a clean break between them. By accessing our SessionHandler
class through a property we can now take our refactoring one step further and employ the Dependency Inversion Principle.
Instead of relying on a concrete implementation of SessionHandler
, why don't we abstract the storing of Application State variables behind an interface. One that looks like this:
public interface IApplicationState
{
public T GetValue<T>(String key);
public SetValue(String key, Object val);
}
Now we can simply change over our property inside of EditMapUtlities
to use the interface, and pass this in through the constructor using good ol' manual Dependency Injection.
public class EditMapUtlities
{
//Omitting the wireup details for now
private IApplicationState ApplicationState {get; set;}
public EditMapUtilities(IApplicationState appState)
{
if(appState == null) throw new ArgumentNullException("appState");
ApplicationState = appState;
}
public static Boolean isInitialEditMapPageLoad
{
get { return ApplicationState.GetValue<Boolean>("EditMapInitialPageLoad"); }
set { ApplicationState.SetValue("EditMapInitialPageLoad", value); }
}
// REST OF CLASS NOT GERMAIN TO DISCUSSION AND OMITTED
}
You can easily refactor your SessionHandler
class to implement the interface and not be static:
public SessionHandler: IApplicationState { //Implementation }
Or if you need to maintain backward compatibility with other areas of code, you could create a wrapper class, and leave SessionHandler static:
public SessionHandlerWrapper: IApplicationState
{
//Call SessionHandler from within this class
}
Now it's true that you will have to manually create your concrete instance of IApplicationState
and pass it into EditMapUtilities
, but now neither class is dependent on the other. In fact, if you ever wanted to store this in the database in the future, you would simply have to write a new class that implemented IApplicationState
. Only the calling code would have to change to use the new database class instead of the session based one.
Now you can enjoy your new loosley coupled architecture and the minimized changes you will have to make to add new functionality.