I am trying attempting to refactor the following code:
public static void SaveSplitbar(RadSplitBar splitBar)
{
Logger.InfoFormat("Saving splitBar {0}", splitBar.ID);
RadSplitBarSetting splitbarSettings = splitBar.GetSettings();
SerializableDictionary<string, RadSplitBarSetting> splitBarStates = GetStates<SerializableDictionary<string, RadSplitBarSetting>>();
bool splitbarIsKnown = splitBarStates.ContainsKey(splitbarSettings.ID);
if (splitbarIsKnown)
{
Logger.Debug("SplitBar is known. Overwriting data.");
splitBarStates[splitbarSettings.ID] = splitbarSettings;
}
else
{
Logger.Debug("SplitBar is unknown. Saving data.");
splitBarStates.Add(splitbarSettings.ID, splitbarSettings);
}
RadControlManager.SetStates<SerializableDictionary<string, RadSplitBarSetting>>(splitBarStates);
}
The logic of the code is reused in saving various other objects. I am trying to make this code more generic so that I will be able to have one Save() method rather than SaveX(), SaveY(), and SaveZ() all performing the same work on different objects.
I have a bit of a snag, however. While all of the objects being passed into Save have the "GetSettings()" method, many of them have this method defined in an extension method:
//RadControlExtensions.cs Extension Methods
public static RadSplitBarSetting GetSettings(this RadSplitBar splitbar)
{
RadSplitBarSetting radSplitbarSetting = new RadSplitBarSetting(splitbar.ID, splitbar.Parent.ID, splitbar.CollapseMode, splitbar.AdjacentPanesNames);
return radSplitbarSetting;
}
As such, when I tried to refactor SaveSplitbar, I realize that I would have to be switching on the type of my parameter. When I started going down this route I thought, "Well, this is stupid, if I have to determine the type of the object I should just write Save multiple times as extension methods for each object."
While this is an "OK" solution, I am unhappy with it. The logic behind saving each type of control is identical and I would prefer not having copy/pasted logic in my extension class.
My next thought was, "Well, if any parameter passed into Save is guaranteed to have a GetSettings method -- maybe there is a way to have an IRadControlExtensions interface which exposes this method. I was unable to determine any such way as each GetSettings method has a different signature - does not seem possible to announce it just once in the interface.
So that's where I am at. How should I be approaching this problem?
EDIT: Another Save method
public static void SavePane(CormantRadPane pane)
{
Logger.InfoFormat("Saving pane {0}", pane.ID);
RadPaneSetting paneSettings = pane.GetSettings();
SerializableDictionary<string, RadPaneSetting> paneStates = GetStates<SerializableDictionary<string, RadPaneSetting>>();
bool paneIsKnown = paneStates.ContainsKey(paneSettings.ID);
if (paneIsKnown)
{
Logger.Debug("Pane is known. Overwriting data.");
paneStates[paneSettings.ID] = paneSettings;
}
else
{
Logger.Debug("Pane is unknown. Saving data.");
paneStates.Add(paneSettings.ID, paneSettings);
}
RadControlManager.SetStates<SerializableDictionary<string, RadPaneSetting>>(paneStates);
}
EDIT2: Perhaps a better question is, "When is it time to stop extending a class and time to start creating a new class which inherits from the class currently being extended?"