I have some debugging functions that I would like to refactor, but seeing as they are debugging functions, it seems like they would be less likely to follow proper design. They pretty much reach into the depths of the app to mess with things.
The main form of my app has a menu containing the debug functions, and I catch the events in the form code. Currently, the methods ask for a particular object in the application, if it's not null, and then mess with it. I'm trying to refactor so that I can remove the reference to this object everywhere, and use an interface for it instead (the interface is shared by many other objects which have no relation to the debugging features.)
As a simplified example, imagine I have this logic code:
public class Logic
{
public SpecificState SpecificState { get; private set; }
public IGenericState GenericState { get; private set; }
}
And this form code:
private void DebugMethod_Click(object sender, EventArgs e)
{
if (myLogic.SpecificState != null)
{
myLogic.SpecificState.MessWithStuff();
}
}
So I'm trying to get rid of the SpecificState reference. It's been eradicated from everywhere else in the app, but I can't think of how to rewrite the debug functions. Should they move their implementation into the Logic class? If so, what then? It would be a complete waste to put the many MessWithStuff methods into IGenericState as the other classes would all have empty implementations.
edit
Over the course of the application's life, many IGenericState instances come and go. It's a DFA / strategy pattern kind of thing. But only one implementation has debug functionality.
Aside: Is there another term for "debug" in this context, referring to test-only features? "Debug" usually just refers to the process of fixing things, so it's hard to search for this stuff.
Create a separate interface to hold the debug functions, such as:
public interface IDebugState
{
void ToggleDebugMode(bool enabled); // Or whatever your debug can do
}
You then have two choices, you can either inject IDebugState the same way you inject IGenericState, as in:
public class Logic
{
public IGenericState GenericState { get; private set; }
public IDebugState DebugState { get; private set; }
}
Or, if you're looking for a quicker solution, you can simply do an interface test in your debug-sensitive methods:
private void DebugMethod_Click(object sender, EventArgs e)
{
var debugState = myLogic.GenericState as IDebugState;
if (debugState != null)
debugState.ToggleDebugMode(true);
}
This conforms just fine with DI principles because you're not actually creating any dependency here, just testing to see if you already have one - and you're still relying on abstractions over concretions.
Internally, of course, you still have your SpecificState implementing both IGenericState and IDebugState, so there's only ever one instance - but that's up to your IoC container, none of your dependent classes need know about it.
I'd highly recommend reading Ninject's walkthrough of dependency injection (be sure to read through the entire tutorial). I know this may seem like a strange recommendation given your question; however, I think this will save you a lot of time in the long run and keep your code cleaner.
Your debug code seems to depend on SpecificState; therefore, I would expect that your debug menu items would ask the DI container for their dependencies, or a provider that can return the dependency or null. If you're already working on refactoring to include DI, then providing your debug menu items with the proper internal bits of your application as dependencies (via the DI container) seems to be an appropriate way to achieve that without breaking solid design principles. So, for instance:
public sealed class DebugMenuItem : ToolStripMenuItem
{
private SpecificStateProvider _prov;
public DebugMenuItem(SpecificStateProvider prov) : base("Debug Item")
{
_prov = prov;
}
// other stuff here
protected override void OnClick(EventArgs e)
{
base.OnClick(e);
SpecificState state = _prov.GetState();
if(state != null)
state.MessWithStuff();
}
}
This assumes that an instance of SpecificState isn't always available, and needs to be accessed through a provider that may return null. By the way, this technique does have the added benefit of fewer event handlers in your form.
As an aside, I'd recommend against violating design principles for the sake of debugging, and have your debug "muck with stuff" methods interact with your internal classes the same way any other piece of code must - by its interface "contract". You'll save yourself a headache =)
I'd be inclined to look at dependency injection and decorators for relatively large apps, as FMM has suggested, but for smaller apps you could make a relatively easy extension to your existing code.
I assume that you push an instance of Logic down to the parts of your app somehow - either though static classes or fields or by passing into the constructor.
I would then extend Logic with this interface:
public interface ILogicDebugger
{
IDisposable PublishDebugger<T>(T debugger);
T GetFirstOrDefaultDebugger<T>();
IEnumerable<T> GetAllDebuggers<T>();
void CallDebuggers<T>(Action<T> call);
}
Then deep down inside your code some class that you want to debug would call this code:
var subscription =
logic.PublishDebugger(new MessWithStuffHere(/* with params */));
Now in your top-level code you can call something like this:
var debugger = logic.GetFirstOrDefaultDebugger<MessWithStuffHere>();
if (debugger != null)
{
debugger.Execute();
}
A shorter way to call methods on your debug class would be to use CallDebuggers like this:
logic.CallDebuggers<MessWithStuffHere>(x => x.Execute());
Back, deep down in your code, when your class that you're debugging is about to go out of scope, you would call this code to remove its debugger:
subscription.Dispose();
Does that work for you?
Related
I have an class which can perform many analytics on a given object and return back sets of results:
public class AnalyserClass
{
private SomeObject _someObject;
public AnalyserClass(SomeObject someobject)
{
_someObject = someobject;
}
public IEnumerable<Result> DoA
{
//checks A on someObject and returns some results
}
public IEnumerable<Result> DoB
{
//checks B on someObject and returns some results
}
//etc
}
public class Result
{
//various properties with result information
}
public class SomeObject
{
//this is the object which is analysed
}
I would like to expose these actions (DoA, DoB etc) in a CheckedListBox in a WinForm. The user would then tick the actions s/he wants performed and would then click on a Run button.
I would ideally like exposing the actions to be dynamic - so, if I develop a new action within my AnalyserClass, it will automatically show up and be executable from the WinForm without any code changes anywhere else.
I am a fairly new C# programmer. I have been researching how best to structure this and I have become a little bit confused between various patterns and which one would be most appropriate to use.
First of all I read up on the MVVM pattern, but this seems to be more complicated than is required here and I don't understand what the Model would be.
Then I looked at the Command pattern. But from what I understand, I would have to create a class wrapper for every single action (there are a lots) which would be quite time consuming and seem to be a bit cumbersome (change code in multiple places, so not 'dynamic'). I also don't understand how I could build the list of checkboxes from the command classes. This does seem to be the most appropriate pattern that I could find, but I am uncertain about it because of my lack of experience.
Your guidance is much appreciated.
I would not choose Reflection here, because it makes the things unnecessary complicated.
Furthermore, with your current approach, you would need to extend your AnalyserClass with new functionality every time you need a new analyzer tool, and that:
breaks the "open-closed" principle of SOLID,
breaks the "single responsibility" principle of SOLID,
makes your class too large and pretty unmaintainable.
I would introduce in your AnalyserClass a collection of supported actions:
class AnalyserClass
{
public IEnumerable<IAnalyzer> Analyzers { get; private set; }
}
...where the IAnalyzer interface describes your actions:
interface IAnalyzer
{
string Description { get; } // this is what user will see as the action name
Result Perform(SomeObject input);
}
Then you can implement the IAnalyzer in various classes as needed, even in different modules etc.
The only open point would be - how to add all the IAnalyzer instances into your AnalyzerClass.Analyzers collection?
Well:
you can use a DI framework (e.g. MEF) and let it discover all the things automatically,
you can inject them manually via DI,
you can use Reflection and scan the types manually,
you can add them manually e.g. in the constructor of the AnalyzerClass (simple but not recommended)
and so on...
New to OOP here. I have defined an interface with one method, and in my derived class I defined another public method. My client code is conditionally instantiating a class of the interface type, and of course the compiler doesn't know about the method in one of the derived classes as it is not part of the underlying interface definition. Here is what I am talking about:
public interface IFileLoader
{
public bool Load();
}
public class FileLoaderA : IFileLoader
{
public bool Load();
//implementation
public void SetStatus(FileLoadStatus status)
{
//implementation
}
}
public class FileLoaderB : IFileLoader
{
public bool Load();
//implementation
//note B does not have a SetStatus method
}
public enum FileLoadStatus
{
Started,
Done,
Error
}
// client code
IFileLoader loader;
if (Config.UseMethodA)
{
loader = new FileLoaderA();
}
else
{
loader = new FileLoaderB();
}
//does not know about this method
loader.SetStatus (FileStatus.Done);
I guess I have two questions:
What should I be doing to find out if the object created at run-time has the method I am trying to use? Or is my approach wrong?
I know people talk of IOC/DI all the time. Being new OOP, what is the advantage of using an IOC in order to say, "when my app asks
for an IFileLoader type, use concrete class x", as opposed to simply
using an App.Config file to get the setting?
Referring to your two questions and your other post I'd recommend the following:
What should I be doing to find out if the object created at run-time has the method I am trying to use? Or is my approach wrong?
You don't necessarily need to find out the concrete implementation at runtime in your client code. Following this approach you kinda foil the crucial purpose of an interface. Hence it's rather useful to just naïvely use the interface and let the concrete logic behind decide what's to do.
So in your case, if one implementation's just able to load a file - fine. If your other implementation is able to the same and a bit more, that's fine, too. But the client code (in your case your console application) shouldn't care about it and just use Load().
Maybe some code says more than thousand words:
public class ThirdPartyLoader : IFileLoader
{
public bool Load(string fileName)
{
// simply acts as a wrapper around your 3rd party tool
}
}
public class SmartLoader : IFileLoader
{
private readonly ICanSetStatus _statusSetter;
public SmartLoader(ICanSetStatus statusSetter)
{
_statusSetter = statusSetter;
}
public bool Load(string fileName)
{
_statusSetter.SetStatus(FileStatus.Started);
// do whatever's necessary to load the file ;)
_statusSetter.SetStatus(FileStatus.Done);
}
}
Note that the SmartLoader does a bit more. But as a matter of separation of concerns its purpose is the loading part. The setting of a status is another class' task:
public interface ICanSetStatus
{
void SetStatus(FileStatus fileStatus);
// maybe add a second parameter with information about the file, so that an
// implementation of this interface knows everything that's needed
}
public class StatusSetter : ICanSetStatus
{
public void SetStatus(FileStatus fileStatus)
{
// do whatever's necessary...
}
}
Finally your client code could look something like the follwing:
static void Main(string[] args)
{
bool useThirdPartyLoader = GetInfoFromConfig();
IFileLoader loader = FileLoaderFactory.Create(useThirdPartyLoader);
var files = GetFilesFromSomewhere();
ProcessFiles(loader, files);
}
public static class FileLoaderFactory
{
public static IFileLoader Create(bool useThirdPartyLoader)
{
if (useThirdPartyLoader)
{
return new ThirdPartyLoader();
}
return new SmartLoader(new StatusSetter());
}
}
Note that this is just one possible way to do what you're looking for without having the necessity to determine IFileLoader's concrete implementation at runtime. There maybe other more elegant ways, which furthermore leads me to your next question.
I know people talk of IOC/DI all the time. Being new OOP, what is the advantage of using an IOC [...], as opposed to simply using an App.Config file to get the setting?
First of all separating of classes' responsibility is always a good idea especially if you want to painlessly unittest your classes. Interfaces are your friends in these moments as you can easily substitute or "mock" instances by e.g. utilizing NSubstitute. Moreover, small classes are generally more easily maintainable.
The attempt above already relies on some sort of inversion of control. The main-method knows barely anything about how to instantiate a Loader (although the factory could do the config lookup as well. Then main wouldn't know anything, it would just use the instance).
Broadly speaking: Instead of writing the boilerplate factory instantiation code, you could use a DI-Framework like Ninject or maybe Castle Windsor which enables you to put the binding logic into configuration files which might best fit your needs.
To make a long story short: You could simply use a boolean appSetting in your app.config that tells your code which implementation to use. But you could use a DI-Framework instead and make use of its features to easily instantiate other classes as well. It may be a bit oversized for this case, but it's definitely worth a look!
Use something like:
if((loader as FileLoaderA) != null)
{
((FileLoaderA)loader).SetStatus(FileStatus.Done);
}
else
{
// Do something with it as FileLoaderB type
}
IoC is normally used in situations where your class depends on another class that needs to be setup first, the IoC container can instantiate/setup an instance of that class for your class to use and inject it into your class usually via the constructor. It then hands you an instance of your class that is setup and ready to go.
EDIT:
I was just trying to keep the code concise and easy to follow. I agree that this is not the most efficient form for this code (it actually performs the cast twice).
For the purpose of determining if a particular cast is valid Microsoft suggests using the following form:
var loaderA = loader as FileLoaderA;
if(loaderA != null)
{
loaderA.SetStatus(FileStatus.Done);
// Do any remaining FileLoaderA stuff
return;
}
var loaderB = loader as FileLoaderB
if(loaderB != null)
{
// Do FileLoaderB stuff
return;
}
I do not agree with using is in the if. The is keyword was designed to determine if an object was instantiated from a class that implements a particular interface, rather than if a cast is viable. I have found it does not always return the expected result (especially if a class implements multiple interfaces through direct implementation or inheritance of a base class).
Previous Post removed; Updated:
So I have a unique issue, which is possibly fairly common though. Properties are quite possibly are most commonly used code; as it requires our data to keep a constant value storage. So I thought how could I implement this; then I thought about how easy Generics can make life. Unfortunately we can't just use a Property in a Generic without some heavy legwork. So here was my solution / problem; as I'm not sure it is the best method- That is why I was seeking review from my peers.
Keep in mind the application will be massive; this is a very simple example.
Abstract:
Presentation Layer: The interface will have a series of fields; or even data to go across the wire through a web-service to our database.
// Interface:
public interface IHolder<T>
{
void objDetail(List<T> obj);
}
So my initial thought was an interface that will allow me to Generically handle each one of my objects.
// User Interface:
public class UI : IHolder
{
void objDetail(List<object> obj)
{
// Create an Instance
List<object> l = new List<object>();
// Add UI Fields:
l.Add(Guid.NewGuid());
l.Add(txtFirst.Text);
l.Add(txtLast.Text);
// l to our obj
obj = l;
return;
}
}
Now I have an interface; which has been used by our UI to put information in. Now; this is where the root of my curiosity has been thrown into the mixture.
// Create an Object Class
public class Customer : IHolder
{
// Member Variable:
private Guid _Id;
private String _First;
private String _Last;
public Guid Id
{
get { return _Id; }
set { _Id = value; }
}
public String First
{
get { return _First; }
set { _First = value; }
}
public String Last
{
get { return _Last; }
set { _Last = value; }
}
public virtual objDetail(List<Customer> obj)
{
// Enumerate through List; and assign to Properties.
}
}
Now this is where I thought it would be cool; if I could use Polymorphism to use the same interface; but Override it to do the method differently. So the Interface utilizes a Generic; with the ability to Morph to our given Object Class.
Now our Object Classes; can move toward our Entity interface which will handle basic Crud Operation.
I know this example isn't the best for my intention; as you really don't need to use Polymorphism. But, this is the overall idea / goal...
Interface to Store Presentation Layer UI Field Value
Implement the Properties to a Desired Class
Create a Wrapper Around my Class; which can be Polymorphed.
Morphed to a Generic for Crud Operation
Am I on the right path; is this taboo? Should I not do this? My application needs to hold each instance; but I need the flexibility to adapt very quickly without breaking every single instance in the process. That was how I thought I could solve the issue. Any thoughts? Suggestions? Am I missing a concept here? Or am I over-thinking? Did I miss the boat and implement my idea completely wrong? That is where I'm lost...
After pondering on this scenario a bit, I thought what would provide that flexibility while still ensuring the code is optimized for modification and business. I'm not sure this is the right solution, but it appears to work. Not only does it work, it works nicely. It appears to be fairly robust.
When is this approach useful? Well, when you intend to decouple your User Interface from your Logic. I'll gradually build each aspect so you can see the entire structure.
public interface IObjContainer<T>
{
void container(List<T> object);
}
This particular structure will be important. As it will store all of the desired content into it.
So to start you would create a Form with a series of Fields.
Personal Information
Address Information
Payment Information
Order Information
So as you can see all of these can be separate Database Tables, but belong to a similar Entity Model you are manipulating. This is quite common.
So a Segregation Of Concern will start to show slightly, the fields will be manipulated and passed through an Interface.
public interface IPersonalInformation
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
So essentially the Interface is passing its variable, to the Interface. So you would culminate an interface to handle that entire form or individual interfaces that you wish to call so that they remain reusable.
So now you have a series of Interfaces, or a single once. But it contains all these variables to use. So you would now create a class:
public class CustomerProperties: IPersonalInformation, IOrderInformation
{
// Implement each Interface Property
}
Now you've created a container that will hold all of your values. What is nifty about this container is you can reuse the same values for another class in your application or choose different ones. But it will logically separate the User Interface.
So essentially this is acting similar to a Repository.
Now you can take these values and perform the desired logic. What becomes wonderful now, is after you've performed your logic you pass the object into our Generic List. Then you simply implement that method in another class for your goal and iterate through your list.
The honesty is it appears to work well and decouple nicely. I feel that it was a lot of work to do something similar to a normal Repository and Unit Of Work, this answers the question but weather or not it is ideal for your project I would look into Repository, Unit Of Work, Segregation Of Concern, Inversion Of Control, and Dependency Injection. They may do this same approach cleaner.
Update:
I thought about it after I wrote this up, I noticed you could actually implement those property values into the Generic List structure bypassing a series of interfaces; but that would introduce consistency issues as you'd have to be aware of what data is being passed in each time, in order. It's possible, but may not be ideal.
Let's say I am defining a browser implementation class for my application:
class InternetExplorerBrowser : IBrowser {
private readonly string executablePath = #"C:\Program Files\...\...\ie.exe";
...code that uses executablePath
}
This might at first glance to look like a good idea, as the executablePath data is near the code that will use it.
The problem comes when I try to run this same application on my other computer, that has a foreign-language OS: executablePath will have a different value.
I could solve this through an AppSettings singleton class (or one of its equivalents) but then no-one knows my class is actually dependent on this AppSettings class (which goes against DI ideias). It might pose a difficulty to Unit-Testing, too.
I could solve both problems by having executablePath being passed in through the constructor:
class InternetExplorerBrowser : IBrowser {
private readonly string executablePath;
public InternetExplorerBrowser(string executablePath) {
this.executablePath = executablePath;
}
}
but this will raise problems in my Composition Root (the startup method that will do all the needed classes wiring) as then that method has to know both how to wire things up and has to know all these little settings data:
class CompositionRoot {
public void Run() {
ClassA classA = new ClassA();
string ieSetting1 = "C:\asdapo\poka\poskdaposka.exe";
string ieSetting2 = "IE_SETTING_ABC";
string ieSetting3 = "lol.bmp";
ClassB classB = new ClassB(ieSetting1);
ClassC classC = new ClassC(B, ieSetting2, ieSetting3);
...
}
}
which will turn easily a big mess.
I could turn this problem around by instead passing an interface of the form
interface IAppSettings {
object GetData(string name);
}
to all the classes that need some sort of settings. Then I could either implement this either as a regular class with all the settings embedded in it or a class that reads data off a XML file, something along the lines. If doing this, should I have a general AppSettings class instance for the whole system, or have an AppSettings class associated to each class that might need one? That certainly seems like a bit of an overkill. Also, have all the application setings in the same place makes it easy to look and see what might be all the changes I need to do when tryign to move the program to different platforms.
What might be the best way to approach this common situation?
Edit:
And what about using an IAppSettings with all its settings hardcoded in it?
interface IAppSettings {
string IE_ExecutablePath { get; }
int IE_Version { get; }
...
}
This would allow for compile-time type-safety. If I saw the interface/concrete classes grow too much I could create other smaller interfaces of the form IMyClassXAppSettings. Would it be a burden too heavy to bear in med/big sized projects?
I've also reading about AOP and its advantages dealing with cross-cutting-concerns (I guess this is one). Couldn't it also offer solutions to this problem? Maybe tagging variables like this:
class InternetExplorerBrowser : IBrowser {
[AppSetting] string executablePath;
[AppSetting] int ieVersion;
...code that uses executablePath
}
Then, when compiling the project we'd also have compile time safety (having the compiler check that we actually implemented code that would weave in data. This would, of course, tie our API to this particular Aspect.
The individual classes should be as free from infrastructure as possible - constructs like IAppSettings, IMyClassXAppSettings, and [AppSetting] bleed composition details to classes which, at their simplest, really only depend on raw values such as executablePath. The art of Dependency Injection is in the factoring of concerns.
I have implemented this exact pattern using Autofac, which has modules similar to Ninject and should result in similar code (I realize the question doesn't mention Ninject, but the OP does in a comment).
Modules organize applications by subsystem. A module exposes a subsystem's configurable elements:
public class BrowserModule : Module
{
private readonly string _executablePath;
public BrowserModule(string executablePath)
{
_executablePath = executablePath;
}
public override void Load(ContainerBuilder builder)
{
builder
.Register(c => new InternetExplorerBrowser(_executablePath))
.As<IBrowser>()
.InstancePerDependency();
}
}
This leaves the composition root with the same problem: it must supply the value of executablePath. To avoid the configuration soup, we can write a self-contained module which reads configuration settings and passes them to BrowserModule:
public class ConfiguredBrowserModule : Module
{
public override void Load(ContainerBuilder builder)
{
var executablePath = ConfigurationManager.AppSettings["ExecutablePath"];
builder.RegisterModule(new BrowserModule(executablePath));
}
}
You could consider using a custom configuration section instead of AppSettings; the changes would be localized to the module:
public class BrowserSection : ConfigurationSection
{
[ConfigurationProperty("executablePath")]
public string ExecutablePath
{
get { return (string) this["executablePath"]; }
set { this["executablePath"] = value; }
}
}
public class ConfiguredBrowserModule : Module
{
public override void Load(ContainerBuilder builder)
{
var section = (BrowserSection) ConfigurationManager.GetSection("myApp.browser");
if(section == null)
{
section = new BrowserSection();
}
builder.RegisterModule(new BrowserModule(section.ExecutablePath));
}
}
This is a nice pattern because each subsystem has an independent configuration which gets read in a single place. The only benefit here is a more obvious intent. For non-string values or complex schemas, though, we can let System.Configuration do the heavy lifting.
I'd go with the last option - pass in an object that complies with the IAppSettings interface. In fact, I recently performed that refactor at work in order to sort out some unit tests and it worked nicely. However, there were few classes dependent on the settings in that project.
I'd go with creating a single instance of the settings class, and pass that in to anything that's dependant upon it. I can't see any fundamental problem with that.
However, I think you've already thought about this and seen how it can be a pain if you have lots of classes dependent on the settings.
If this is a problem for you, you can work around it by using a dependency injection framework such as ninject (sorry if you're already aware of projects like ninject - this might sound a bit patronizing - if you're unfamiliar, the why use ninject sections on github are a good place to learn).
Using ninject, for your main project you can declare that you want any class with a dependency on IAppSettings to use a singleton instance of your AppSettings based class without having to explicitly pass it in to constructors everywhere.
You can then setup your system differently for your unit tests by stating that you want to use an instance of MockAppSettings wherever IAppSettings is used, or by simply explicitly passing in your mock objects directly.
I hope I've got the gist of your question right and that I've helped - you already sound like you know what you're doing :)
In wanting to get some hands-on experience of good OO design I've decided to try to apply separation of concerns on a legacy app.
I decided that I wasn't comfortable with these calls being scattered all over the code base.
ConfigurationManager.AppSettings["key"]
While I've already tackled this before by writing a helper class to encapsulate those calls into static methods I thought it could be an opportunity to go a bit further.
I realise that ultimately I should be aiming to use dependency injection and always be 'coding to interfaces'. But I don't want to take what seems like too big a step. In the meantime I'd like to take smaller steps towards that ultimate goal.
Can anyone enumerate the steps they would recommend?
Here are some that come to mind:
Have client code depend on an interface not a concrete implementation
Manually inject dependencies into an
interface via constructor or property?
Before going to the effort of
choosing and applying an IoC
container how do I keep the code
running?
In order to fulfil a dependency the default
constructor of any class that needs a
configuration value could use a Factory
(with a static CreateObject() method)?
Surely I'll still have a concrete dependency on the Factory?...
I've dipped into Michael Feathers' book so I know that I need to introduce seams but I'm struggling to know when I've introduced enough or too many!
Update
Imagine that Client calls methods on WidgetLoader passing it the required dependencies (such as an IConfigReader)
WidgetLoader reads config to find out what Widgets to load and asks WidgetFactory to create each in turn
WidgetFactory reads config to know what state to put the Widgets into by default
WidgetFactory delegates to WidgetRepository to do the data access, which reads config to decide what diagnostics it should log
In each case above should the IConfigReader be passed like a hot potato between each member in the call chain?
Is a Factory the answer?
To clarify following some comments:
My primary aim is to gradually migrate some app settings out of the config file and into some other form of persistence. While I realise that with an injected dependency I can Extract and Override to get some unit testing goodness, my primary concern is not testing so much as to encapsulate enough to begin being ignorant of where the settings actually get persisted.
When refactoring a legacy code-base you want to iteratively make small changes over time. Here is one approach:
Create a new static class (i.e. MyConfigManager) with a method to get the app setting (i.e. GetAppSettingString( string key )
Do a global search and replace of "ConfigurationManager.AppSettings["key"] and replace instances with "MyConfigManager.GetAppSettingsString("key")"
Test and check-in
Now your dependency on the ConfigurationManager is in one place. You can store your settings in a database or wherever, without having to change tons of code. Down side is that you still have a static dependency.
Next step would be to change MyConfigManager into a regular instance class and inject it into classes where it is used. Best approach here is to do it incrementally.
Create an instance class (and an interface) alongside the static class.
Now that you have both, you can refactor the using classes slowly until they are all using the instance class. Inject the instance into the constructor (using the interface). Don't try for the big bang check-in if there are lots of usages. Just do it slowly and carefully over time.
Then just delete the static class.
Usually its very difficult to clean a legacy application is small steps, because they are not designed to be changed in this way. If the code is completely intermingled and you have no SoC it is difficult to change on thing without being forced to change everything else... Also it is often very hard to unit test anything.
But in general you have to:
1) Find the simplest (smallest) class not refactored yet
2) Write unit tests for this class so that you have confidence that your refactoring didn't break anything
3) Do the smallest possible change (this depends on the project and your common sense)
4) Make sure all the tests pass
5) Commit and goto 1
I would like to recommend "Refactoring" by Martin Fowler to give you more ideas: http://www.amazon.com/exec/obidos/ASIN/0201485672
For your example, the first thing I'd do is to create an interface exposing the functionality you need to read config e.g.
public interface IConfigReader
{
string GetAppSetting(string key);
...
}
and then create an implementation which delegates to the static ConfigurationManager class:
public class StaticConfigReader : IConfigReader
{
public string Get(string key)
{
return ConfigurationManager.AppSetting[key];
}
}
Then for a particular class with a dependency on the configuration you can create a seam which initially just returns an instance of the static config reader:
public class ClassRequiringConfig
{
public void MethodUsingConfig()
{
string setting = this.GetConfigReader().GetAppSetting("key");
}
protected virtual IConfigReader GetConfigReader()
{
return new StaticConfigReader();
}
}
And replace all references to ConfigManager with usages of your interface. Then for testing purposes you can subclass this class and override the GetConfigReader method to inject fakes so you don't need any actual config file:
public class TestClassRequiringConfig : ClassRequiringConfig
{
public IConfigReader ConfigReader { get; set; }
protected override IConfigReader GetConfigReader()
{
return this.ConfigReader;
}
}
[Test]
public void TestMethodUsingConfig()
{
ClassRequiringConfig sut = new TestClassRequiringConfig { ConfigReader = fakeConfigReader };
sut.MethodUsingConfig();
//Assertions
}
Then eventually you will be able to replace this with property/constructor injection when you add an IoC container.
EDIT:
If you're not happy with injecting instances into individual classes like this (which would be quite tedious if many classes depend on configuration) then you could create a static configuration class, and then allow temporary changes to the config reader for testing:
public static class Configuration
{
private static Func<IConfigReader> _configReaderFunc = () => new StaticConfigReader;
public static Func<IConfigReader> GetConfiguration
{
get { return _configReaderFunc; }
}
public static IDisposable CreateConfigScope(IConfigReader reader)
{
return new ConfigReaderScope(() => reader);
}
private class ConfigReaderScope : IDisposable
{
private readonly Func<IConfigReader> _oldReaderFunc;
public ConfigReaderScope(Func<IConfigReader> newReaderFunc)
{
this._oldReaderFunc = _configReaderFunc;
_configReaderFunc = newReaderFunc;
}
public void Dispose()
{
_configReaderFunc = this._oldReaderFunc;
}
}
}
Then your classes just access the config through the static class:
public void MethodUsingConfig()
{
string value = Configuration.GetConfigReader().GetAppSetting("key");
}
and your tests can use a fake through a temporary scope:
[Test]
public void TestMethodUsingConfig()
{
using(var scope = Configuration.CreateConfigScope(fakeReader))
{
new ClassUsingConfig().MethodUsingConfig();
//Assertions
}
}