I've just finished reading "Domain-driven design: tackling complexity in the heart of software" by Eric Evans and I'm attempting to write my first domain-centric application (in C#).
The application will be used by our helpdesk to track the allocation of computers to users.
I've sketched a simple class diagram to reflect part of the domain. It looks like this...
Class diagram showing two classes: Owner and Computer. There is a one-way associate between Computer and Owner named 'Allocate to' http://www.freeimagehosting.net/uploads/183dd57031.jpg
I've also identified my first feature (to allocate a computer to a user) and have written a test for it...
[Test]
public void AllocateToUser()
{
var user = new Owner("user1");
var computer = new Computer("computer1");
computer.Allocate(user);
Assert.AreEqual(user.Username, computer.AllocatedTo.Username);
}
Lastly, I've written code to make the test pass.
public class Computer
{
public Computer(string name)
{
Name = name;
}
public string Name
{ get; private set; }
public Owner AllocatedTo
{ get; private set; }
public void Allocate(Owner owner)
{
AllocatedTo = owner;
}
}
public class Owner
{
public Owner(string username)
{
Username = username;
}
public string Username
{ get; private set; }
}
So far, so good (I think).
However, clearly none of this addresses persistence. I think I need to introduce a repository class for Computer. Something like this perhaps:
public class ComputerRepository
{
public void Store(Computer computer)
{
//Some persistence logic here (possibly using NHibernate?)
}
}
Now I'm stuck. How do ensure that changes made to a computer's allocated user are passed to the repository?
I seem to have the following options:
Modify the implementation of the Allocate method of the Computer class to instanstiate an instance of ComputerRepositry and invoke the Store method.
Create an interface IComputerRepository; modify the constructor of Computer to demand that an instance of a class implemeting IComputerRepository is supplied. Within the Allocate method, call Store against this injected instance.
Create a service (AllocationService) that will wrap up a call to Allocate and Store.
Pass resposibility to the client, forcing two steps for the calling code:
Invoke Allocate on an instance of the Computer class
Instantiate an instance of the ComputerRepository and call Store.
None of these seem satisfactory:
is hard to test, as I'd be instantiating the repository directly within the Computer class.
avoids this problem, by using dependency-injection. However it is still ugly, as I need to pass in some instance of IComputerRepository every time I want to instantiate Computer.
is too procedural, failing to encapsulate the behaviour within domain entity classes.
just seems ugly.
What should I be doing?
Usually I would treat behaviour and persistence as two different concerns and test them separately.
The Domain objects should remain oblivious to the existence of Repositories (though clearly not the other way round).
What we've done in this situation is to create a Controller (or a Service) that is responsible for loading the appropriate objects from their Repositories, invoking the behaviour on the objects then calling the Repositories to persist the updates.
You can then test the controller using a Mock repository to check that the controller is calling the repository with the updated objects.
Related
I'm writing a CAD program. Let's say I have in input class, this class reads various data from a text file and creates lots of lists/dictionaries and .... These data need to be accessed by other methods in other classes to be modified. Now here is how I have done it so far:
I have one static class: Building.cs When I create/or load a project this class holds all the data like list of columns, beams, points, etc. All of these are stored as private fields. I can access these using the class's public methods like GetColumns or GetPoints ...
Now I also have non-static classes. They contain 2-3 public methods. and do some stuff on various parts of the building.
public static class Building
{
private static List<Column> columns;
private static List<Beams> beams;
private static List<Points> points;
public static List<Column> GetColumns()
{
return Columns;
}
}
public class ColumnsService()
{
private List<Columns> columns;
public GroupColumns(List<Columns> columns)
{
this.columns = columns;
}
public void Group()
{
// group columns
}
}
var columns = Building.GetColumns();
var columnsService = new ColumnsService(columns);
columnsService.Group();
I was wondering is this the way to go? How else can I store the data. The data needs to be accessible throughout the lifetime of the program to most of the classes. What are the best practices.
What, semantically, is a Building?
To me, the name implies that it's an instance of a structure. That, in the overall business domain, there can be many "buildings" and at any given moment one is interacting with one of them.
If that's the case, then it seems unintuitive to me to make it static. If there's more than one, it should be an instance model. It would contain attributes which describe it and operations which interact with it. The business domain being modeled should drive the structure of this object before any consideration is given to how other objects are going to interact with it.
So let's assume we make it an instance model:
public class Building
{
// attributes and operations
}
Then, as you ask, how do other objects interact with it?
Depends on the interactions.
Let's say an object needs to "render" a building in some way. Let's call it BuildingPrinter for lack of a better term. Clearly it needs a Building to "print". So it requires one for that operation:
public class BuildingPrinter
{
public void Print(Building building)
{
// implementation
}
}
Or perhaps you have an object which "wraps" a building in some way. Something which can't meaningfully exist without a building, regardless of the operations performed. I can't think of one for that particular business domain, so let's just call it a BuildingWidget. Since it needs a building to exist at all, it requires one:
public class BuildingWidget
{
private Building currentBuilding;
private BuildingWidget() { }
public BuildingWidget(Building building)
{
currentBuilding = building;
}
}
The point is, from the perspective of the models which construct the overall domain, if something is required then it must be supplied. The models shouldn't go out to some global data store, tightly coupling with that data store, to get what they need. This is called the Dependency Inversion Principle.
But where will the consuming code which orchestrates the interactions of these models get instances of a Building? There are a number of potential solutions to that.
Two common patterns would be to have a static factory or a repository. For example:
public class BuildingFactory
{
public static Building FetchBuilding(int buildingId)
{
// implementation
}
}
This factory might have a static cached building object. The building itself isn't static, but for performance reasons an instance of it is cached statically so that it's not constantly re-fetched from a backing data store (such as a database). You might also add methods to invalidate the cache and re-fetch, or encapsulate that logic into the factory itself (such as always re-fetch after 5 minutes or after 10 accesses or some other rule). (Behind the scenes, this factory might even use a repository, shown below, to re-fetch that instance. In which case, you guessed it, a BuildingRepository would be required on the BuildingFactory constructor.)
This factory object may also be responsible for creating a building based on some specifications, if for example you have reason to make the Building constructor private.
Or, to re-fetch from data, consider a repository:
public class BuildingRepository
{
public Building GetBuilding(int buildingId)
{
// fetch from database
}
public Building SaveBuilding(Building building)
{
// save to database, return updated version
}
}
Then other code throughout the domain, including the consuming code, can use these objects to get/save buildings. The factory is static, so that can be invoked anywhere. The repository is instance but doesn't need to be globally distinct, so that can be instantiated anywhere (or pulled form a dependency injection container).
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.
I have debated this for a while now and still have not come to a conclusion.
While most examples I see have the factories code in the application layer I tend to think it should be in the domain layer.
Reasons for this:
I sometimes have initial validation done in my factory where I want all creation of objects to go through.
I want this code to be used on all instantiates of my object.
Sometimes an operation requires parameter information which feels unnatural to pass to a constructor.
And a few more not as important reasons.
Are there reasons why this is a bad practice?
Does this break other patterns?
A factory in DDD is just an instance of the factory pattern and as such it should be used where it makes the most sense. Another principle to consider is the information expert pattern which essentially states that behavior should be assigned to classes closest to the information. Therefore, if you have some domain specific rules and logic you would like to enforce, place the factory in the domain layer - after all, the factory creates domain objects. Note however that you may have other types of factories in other layers.
From memory, Eric Evans' book has examples where object factories are very much part of the domain layer.
For me, it makes perfect sense to locate your factories here.
+1 for doing that. Accessibility would be a good reason, I would keep the creational code at least close to the domain model layer. Otherwise users of the domain model will get simply confused how to instantiate it specially when finding restricted access constructors. Actually one sound reason to separate it would be that you have different valid ways to create the same thing e.g. which is the case usually when employing the Abstract Factory.
If I had to separate it I would put it in e.g. a package (in the case of Java) at least the same level of the domain model and ship it always along with it e.g.
upper
--> domain
--> domain_factory
I prefer Factories in the Application Layer.
If you keep the Factories in the Domain Layer, they will not help you when you need complex types as parameters (C# code example):
Application Layer:
//this Factory resides in the Domain Layer and cannot reference anything else outside it
Person person = PersonAggregateFactory.CreateDeepAndLargeAggregate(
string name, string code, string streetName,...
and lots of other parameters...);
//these ones reside in Application Layer, thus can be much more simple and readable:
Person person = PersonAggregateFactory.CreateDeepAndLargeAggregate(CreatePersonCommand);
Person person = PersonAggregateFactory.CreateDeepAndLargeAggregate(PersonDTO);
Domain Layer:
public class Person : Entity<Person>
{
public Address Address {get;private set;}
public Account Account {get;private set;}
public Contact Contact {get;private set;}
public string Name {get;private set;}
public Person(string name, Address address,Account account, Contact contact)
{
//some validations & assigning values...
this.Address = address;
//and so on...
}
}
public class Address:Entity<Address>{
public string Code {get;private set;}
public string StreetName {get;private set;}
public int Number {get;private set;}
public string Complement {get;private set;}
public Address(string code, string streetName, int number, string complement?)
{
//some validations & assigning values...
code = code;
}
}
public class Account:Entity<Account>{
public int Number {get;private set;}
public Account(int number)
{
//some validations & assigning values...
this.Number = number;
}
}
//yout get the idea:
//public class Contact...
Also, there is no obligation on keeping Factories inside the Domain Layer (from Domain Driven Design Quickly):
Therefore, shift the responsibility for creating instances of complex
objects and Aggregates to a separate object, which may itself have
no responsibility in the domain model but is still part of the
domain design. Provide an interface that encapsulates all complex
assembly and that does not require the client to reference the
concrete classes of the objects being instantiated. Create entire
Aggregates as a unit, enforcing their invariants.
As I don't use Factories to load persisted objects into memory, they don't have to be accessible from other layers than Application's. Here's why (from Domain Driven Design Quickly):
Another observation is that Factories need to create new objects
from scratch, or they are required to reconstitute objects which
previously existed, but have been probably persisted to a
database. Bringing Entities back into memory from their resting
place in a database involves a completely different process than
creating a new one. One obvious difference is that the new
object does not need a new identity. The object already has one.
Violations of the invariants are treated differently. When a new
object is created from scratch, any violation of invariants ends
up in an exception. We can’t do that with objects recreated from
a database. The objects need to be repaired somehow, so they
can be functional, otherwise there is data loss.
If builders/factories only have dependencies on domain classes and primitives, place them in the domain layer, otherwise place them outside the domain layer.
CAREFUL with placing 'implementation' in the Domain Layer.
Your domain code doesn't have dependencies. So, you are in trouble if you need to have complex factories.
For example:
// DOMAIN LAYER
public interface IAggregateFactory<TAgg, in TInput>
{
Task<TAgg> CreateAsync(TInput input);
}
public class AvailabilityFactoryParameters
{
public string SomeInputParameter { get; set; }
public string ZipCode { get; set; }
}
// INFRASTRUCTURE/APPLICATION LAYER
public class AvailabilityFactory : IAggregateFactory<GamePredictorAggregate,
GamePredictorFactoryParameters>
{
private readonly HttpClient _httpClient;
public AvailabilityFactory(IHttpClientFactory factory)
{
_httpClient = factory.CreateClient("weatherApi");
}
public async Task<GamePredictorAggregate> CreateAsync(GamePredictorFactoryParameters input)
{
var weather = await _httpClient.GetFromJsonAsync<WeatherDto>($"/weather/{input.ZipCode}");
return new GamePredictorAggregate(weather.CurrentTemperature, input.SomeInputParameter);
}
}
public class WeatherDto
{
public double CurrentTemperature { get; set; }
}
As you can see, now you have a myriad of objects and dependencies available to enrich your factory experience.
So, when you use it in your Application Service, it is easy...
public class GamePredictionService : ApplicationService
{
private readonly IAggregateFactory<GamePredictorAggregate, GamePredictorFactoryParameters> _factory;
public GamePredictionService(IAggregateFactory<GamePredictorAggregate, GamePredictorFactoryParameters> factory)
{
_factory = factory;
}
public async Task CreateNewPredictor(string zipCode, int someOtherParamater)
{
var input = new GamePredictorFactoryParameters();
input.ZipCode = zipCode;
input.SomeInputParameter = someOtherParamater;
var aggregate = await _factory.CreateAsync(input);
// Do your biz operations
// Persist using repository
}
}
Now your application service doesn't need to worry about the internals, and your domain objects need to understand how the factory gives them 'birth.'
Summary: Having your implementation in the Domain layer makes only sense if your factory only needs primitive types and nothing else. In cases where you may need to gather data from external services or other application services' DTOs, you want to move the implementation outside.
The only 'drawback' is that you need to 'inject' the factory into your application service, but that's not a big deal.
I hope this answer helps to clarify 'where to place Factories.'
I have a User entity which has a HasCompletedSecurity property which indicates whether that particular User has answered the number of security questions required by the system. The number of security questions the system requires is configurable and retrieved from a config file. How should the User class access the configured information?
I currently have an IConfigurationService interface behind which I have implementations which use the ConfigurationManager or the Azure equivalent if it is available. I've encapsulated access to my DI container through a static InjectionService class, and am currently resolving the configured value like so:
public class User
{
private static readonly IConfigurationService _configurationService =
InjectionService.Resolve<IConfigurationService>();
public bool HasCompletedSecurity
{
get
{
// Uses the static _configurationService to get the
// configured value:
int numberOfRequiredResponses =
GetConfiguredNumberOfRequiredResponses();
return this.SecurityQuestionResponses.Count()
>=
GetConfiguredNumberOfRequiredResponses();
}
}
}
This is of course an example of the ServiceLocator anti-pattern, and I don't like it one bit. The static dependency makes unit testing anything which uses this class awkward.
I'm using the Entity Framework and taking a cue from here I don't want to pass my entities through a DI container to give them their dependencies, so... how should I be accessing the configured value instead?
Edit: With this exact example to one side (and I do appreciate the suggestions as to the correct architecture for it), the larger question I'm interested in is how do you manage non-static references to services from entities? Is the answer to just architect the entities in such a way that you never need to?
Here's how I would define the User class:
public class User
{
public bool HasCompletedSecurity { get; set; }
// other members...
}
Seriously, this is a better solution because it decouples the value along the temporal dimension. Consider this: if a user completed all security questions in 2010 and you later on change the business rule, are you then going to invalidate the existing user?
In most cases it would probably be more reasonable to record and persist that sometime in the past, the user completed the security procedure that was in effect at that time. In that way, you don't bother existing users.
You can still using the concept of Inversion of Control without using any sort IoC container or requiring its use in the constructor of your entity. I would approach this using a quasi-strategy pattern and have something like:
public interface ISecurityPolicy
{
public int MinimumSecurityQuestionResponses { get; }
}
public class User
{
public void HasCompletedSecurity (ISecurityPolicy security_policy)
{
return this.SecurityQuestionResponses.Count()
>= security_policy.MinimumSecurityQuestionResponses;
}
}
This puts the onus of providing the particular security policy that the user must satisfy on the caller, not the User class itself.
From that point on, you can provide that extra parameter however you want to, maybe be wrapping this in a IUserSecurityService that will have the ISecurityPolicy injected into the service, etc.
This is still Inversion of Control, but it's at the method level, since this one particular method is really the only one that cares about the security policy/configuration.
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
}
}