I have a class with the following structure
class Measure
{
public MeasureType measureType { get; set; }
public readonly IMeasureService _service ;
public Measure(IMeasureService service)
{
_service = service;
}
public Calculate()
{
_service.Calculate(this);
}
}
So i have different implementation of MeasureService for different measureTypes. Is it possible to use StructureMap to inject the corresponding MeasureService based on the measureType.
MeasureType is just an enum type and will never get changed throughout the instance.
StructureMap cannot be instructed to do that for a simple reason:
at the time the instance is created, the measureType property cannot be set.
you cannot set the IMeasureService dependency at a later time, because it's readonly (and should probably be private as well)
Therefore, the solutions to this problem have more to do with the design of your classes than with StructureMap.
Here are the solutions I would typically choose in such a scenario:
1) Delegate the task of choosing the right IMeasureService implementation to a different component.
The component could, for example, be called MeasureServiceFactory and have the following implementation:
public class MeasureServiceFactory
{
private readonly Func<MeasureServiceType1> _type1Service;
private readonly Func<MeasureServiceType2> _type2Service;
public MeasureServiceFactory(
Func<MeasureServiceType1> type1Service,
Func<MeasureServiceType2> type2Service)
{
_type1Service = type1Service;
_type2Service = type2Service;
}
public IMeasureService GetServiceForType(MeasureType type)
{
switch (type)
{
case MeasureType.Type1:
return _type1Service();
case MeasureType.Type2:
return _type2Service();
default:
throw new ApplicationException("Unexpected measure type!");
}
}
}
Note that StructureMap will automatically inject the two Funcs with appropriate calls to the container's GetInstance() method in order to properly resolve the required service.
Now, the Measure class will no longer have a direct IMeasureService dependency, but will depend on the factory instead:
public class Measure
{
public MeasureType measureType { get; set; }
private readonly MeasureServiceFactory _measureServiceFactory;
public Measure(MeasureServiceFactory measureServiceFactory)
{
_measureServiceFactory = measureServiceFactory;
}
public void Calculate()
{
var service = _measureServiceFactory.GetServiceForType(measureType);
service.Calculate(this);
}
}
Note that no StructureMap configuration is required. The container will be able to resolve everything correctly.
2) In order to keep the Measure class untouched, you could make the MeasureServiceFactory implement the IMeasureService interface:
public class MeasureServiceFactory : IMeasureService
{
private readonly Func<MeasureServiceType1> _type1Service;
private readonly Func<MeasureServiceType2> _type2Service;
public MeasureServiceFactory(
Func<MeasureServiceType1> type1Service,
Func<MeasureServiceType2> type2Service)
{
_type1Service = type1Service;
_type2Service = type2Service;
}
public void Calculate(Measure measure)
{
var service = GetServiceForType(measure.measureType);
service.Calculate(measure);
}
private IMeasureService GetServiceForType(MeasureType type)
{
switch (type)
{
case MeasureType.Type1:
return _type1Service();
case MeasureType.Type2:
return _type2Service();
default:
throw new ApplicationException("Unexpected measure type!");
}
}
}
Now, with your original Measure class, only this SM configuration is required to ake everything work:
x.For<IMeasureService>().Use<MeasureServiceFactory>();
3) If the logic inside the IMeasureService implementors is not very complicated, consider putting it in a single class and perform different things depending on the measureType of the Measure object (which you already have access to).
I know, this seems like a step back, but there are some cases in which I prefer to do just that: when the business logic is not overly complex and pretty unlikely to change.
Related
I've been struggling with a small DI problem, that I think should be very easy to solve, but for some reason I can't find the solution.
I have a service that should one one DI object in the same way for two different things.
public class EquationManager : IEquationManager
{
private readonly IEquationEvaluator _equationEvaluator;
private readonly IEquationEvaluator _inversEquationEvaluator;
public EquationManager(IEquationEvaluator equationEvaluator)
{
_equationEvaluator = equationEvaluator;
_inversEquationEvaluator = equationEvaluator;
}
}
So what I would need is 2 instances of the same DI. That's all. If I write the code as it is, they are shallow copies, what ever I set to _inversEquationEvaluator is also updated in _equationEvaluator ( which is normal).
How do I have 2 separate instances of the same DI? Is this possible in a simple way. I would like to avoid registering IEquationEvaluator in 2 different ways in the container.
My second question: is my architecture wrong? What I want to achieve here is having an math equation that takes an input parameter (int) and output a double value. I need now a way to revert this process using an other equation. So I input a double value and in theory I should obtain an int value. IEquationEvaluator is a class that deals with the math operation.
You can use this pattern:
public enum EquationEvaluatorType
{
EquationEvaluator,
InversEquationEvaluator
}
public interface IEquationEvaluator
{
public EquationEvaluatorType Type { get; }
//your methods and properties
}
public class EquationEvaluator : IEquationEvaluator
{
public EquationEvaluatorType Type => EquationEvaluatorType.EquationEvaluator;
}
public class InversEquationEvaluator : IEquationEvaluator
{
public EquationEvaluatorType Type => EquationEvaluatorType.InversEquationEvaluator;
}
public class EquationManager : IEquationManager
{
private readonly IEquationEvaluator _equationEvaluator;
private readonly IEquationEvaluator _inversEquationEvaluator;
public EquationManager(IEnumerable<IEquationEvaluator> items)
{
_equationEvaluator = items.First(x=>x.Type==EquationEvaluatorType.EquationEvaluator);
_inversEquationEvaluator = items.First(x => x.Type == EquationEvaluatorType.InversEquationEvaluator);
}
}
And in your startup:
services.AddScoped<IEquationEvaluator, EquationEvaluator>();
services.AddScoped<IEquationEvaluator, InversEquationEvaluator>();
I am applying the Service Locator pattern as described in Game Programming Patterns, and am wondering about a possible generic implementation. The following code does work, but I am confused about using a class that is both generic and static.
The idea of the following C# code is to provide a "global" service to other parts of the application, exposing only an interface rather than the full implementation. Each service registered using this method will only have one instance in the application, but I want to be able to easily swap in/out different implementations of the provided interfaces.
My question is: when I use the following class to provide different services throughout my application, how does C# know that I am referring to different services of different types? Intuitively, I would almost think that the static variable, _service, would be overridden with each new service.
public static class ServiceLocator<T>
{
static T _service;
public static T GetService()
{
return _service;
}
public static void Provide(T service)
{
_service = service;
}
}
Here's some usage:
// Elsewhere, providing:
_camera = new Camera(GraphicsDevice.Viewport);
ServiceLocator<ICamera>.Provide(_camera);
// Elsewhere, usage:
ICamera camera = ServiceLocator<ICamera>.GetService();
// Elsewhere, providing a different service:
CurrentMap = Map.Create(strategy);
ServiceLocator<IMap>.Provide(CurrentMap);
// Elsewhere, using this different service:
IMap map = ServiceLocator<IMap>.GetService();
C# creates a separate closed type for every combination of generic parameters for open type.
Since every combination of generic parameters creates a separate class, calling a static constructor and creating own members for each of them.
You can think of them like of different classes.
public static class GenericCounter<T>
{
public static int Count { get; set; } = 0;
}
GenericCounter<int>.Count++;
GenericCounter<int>.Count++;
GenericCounter<string>.Count++;
Console.WriteLine(GenericCounter<double>.Count); // 0
Console.WriteLine(GenericCounter<int>.Count); // 2
Console.WriteLine(GenericCounter<string>.Count); // 1
This code outputs:
0
2
1
For example, in your case, behavior will be the same as if you created two separate classes:
public static class ServiceLocatorOfIMap
{
static IMap _service;
public static IMap GetService()
{
return _service;
}
public static void Provide(IMap service)
{
_service = service;
}
}
public static class ServiceLocatorOfICamera
{
static ICamera _service;
public static ICamera GetService()
{
return _service;
}
public static void Provide(ICamera service)
{
_service = service;
}
}
and used it like this:
// Elsewhere, providing:
_camera = new Camera(GraphicsDevice.Viewport);
ServiceLocatorForICamera.Provide(_camera);
// Elsewhere, usage:
ICamera camera = ServiceLocatorForICamera.GetService();
// Elsewhere, providing a different service:
CurrentMap = Map.Create(strategy);
ServiceLocatorForIMap.Provide(CurrentMap);
// Elsewhere, using this different service:
IMap map = ServiceLocatorForIMap.GetService();
In general, it is similar to what C# does when it meets static generic classes.
I use this for cases where I can't use dependency injection all the way down (like WebForms) but I want to write testable classes that are resolved by a DI container.
The usage looks like
using(var resolved = new ResolvedService<ISomeService>())
{
resolved.Service.DoSomething();
}
The good:
You can use a DI container to resolve and release resources
It's disposable, and disposing causes the container to release the resources
It keeps the container and service registrations out of sight
The bad:
It requires a static class, but that's also in the composition root so it's not too bad.
As written it depends directly on Windsor. It's easy to replace that with any other container. Maybe one day I'll break this apart so that ServiceLocator isn't coupled to any particular container. But for now it's trivial to change that.
Using this means that while the larger component (like an .aspx page) isn't testable, what I inject into it is testable. It just gave me a crazy thought - I could write orchestrators for WebForms pages so that they're mostly testable. But hopefully I'll never need to do that.
internal class ServiceLocator
{
private static IWindsorContainer _container;
internal static void Initialize(IWindsorContainer container)
{
_container = container;
}
internal static TService Resolve<TService>(string key = null)
{
if (_container == null)
{
throw new InvalidOperationException(
"ServiceLocator must be initialized with a container by calling Initialize(container).");
}
try
{
return string.IsNullOrEmpty(key)
? _container.Resolve<TService>()
: _container.Resolve<TService>(key);
}
catch (ComponentNotFoundException ex)
{
throw new InvalidOperationException(string.Format("No component for {0} has been registered.", typeof(TService).FullName), ex);
}
}
internal static void Release(object resolved)
{
_container.Release(resolved);
}
}
public class ResolvedService<TService> : IDisposable
{
private bool _disposed;
private readonly TService _resolvedInstance;
public TService Service
{
get { return _resolvedInstance; }
}
public ResolvedService(string key = null)
{
_resolvedInstance = ServiceLocator.Resolve<TService>(key);
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
~ResolvedService()
{
Dispose(false);
}
protected virtual void Dispose(bool disposing)
{
if (_disposed) return;
ServiceLocator.Release(_resolvedInstance);
_disposed = true;
}
}
I've implemented the command pattern (in a multi-support way) in my application.
Structure:
class MultiCommand : BaseCommand
abstract class BaseCommand : ICommand
Process Flow:
var commandsGroup = new MultiCommand(new List<ICommand>()
{
new Command1(),
new Command2(),
new Command3(),
});
commandsGroup.Execute()
Now, suppose that in Command1 a somethingID is changed and I'll use this new value in Command2... And also, that there are plenty of other properties and objects that are being affected during the whole execution process.
Also, there are some interface implementations that should be available at any command just using the context object like:
Context.ServerController.something();
The instantiation of the IServerController will take place just before the multiCommandGroup initialization.
How can I have a shared context like this for all Commands of the group?
Example of the Context class:
public class CommandContext
{
public IServerController ServerController;
public RequiredData Data { get; set; }
public CommandContext(){}
}
IMPORTANT
A minimal implementation Code is here
1) If you want to keep this interface, then you have to pass this context as constructor parameter:
new MultiCommand(new List<ICommand>()
{
new Command1(context),
new Command2(context),
new Command3(context),
})
2) As another option you can accept list of delegates instead of list of commands.
MultiCommand will be look like this:
class MultiCommand : ICommand
{
public MultiCommand(List<Func<Context, Command>> commands, Context context)
}
That is almost the same except MultiCommand is responsible for all the commands share the same context.
3) Looks like commands in MultiCommand depends on result of previous command. In this case Command pattern is not probably the best. Maybe you should try to implement Middleware chain here?
interface IMiddleware<TContext>
{
void Run(TContext context);
}
class Chain<TContext>
{
private List<IMiddleware<TContext>> handlers;
void Register(IMiddleware<TContext> m);
public void Run(TContext context)
{
handlers.ForEach(h => h.Run(context));
}
}
I would suggest to make somethings generic. Here is a super simple example.
class MultiCommand<TContext>
{
List<Command<TContext>> Commands;
TContext Context;
}
You could have a constructor on your BaseCommand class (and its derived classes) that would accept a Context class of some kind. When instantiating the commands that will belong to the same group, you could provide them all the same context object. Maybe something like:
public class CommandContext
{
// The object that will be the target of the commands' actions.
public object Data { get; set; }
// ... any other properties that might be useful as shared state between commands...
}
public abstract class BaseCommand : ICommand
{
protected CommandContext Context { get; private set; }
public BaseCommand(CommandContext ctx)
{
Context = ctx;
}
}
public class ChangeSomethingIDCommand : BaseCommand
{
public ChangeSomethingIDCommand(CommandContext ctx) : base(ctx)
{ }
public void Execute()
{
var target = (SomeDomainClass)Context.Data;
target.SomethingID++;
}
}
// Elsewhere in your code (assuming 'myTargetDomainClassInstance' is
// a SomeDomainClass instance that has been instantiated elsewhere and
// represents the object upon which the commands will do work):
var ctx = new CommandContext { Data = myTargetDomainClassInstance };
var commandGroup = new MultiItemCommand(ctx, new List<ICommand>
{
new ChangeSomethingIDCommand(ctx),
new Command2(ctx),
new Command3(ctx)
});
commandGroup.Execute();
Consider a Functional Style
public class SomeMainClass{
public void MultiCommandInit()
{
MultiCommand.New()
.Add(new Command1())
.Add(new Command2())
.Add(new Command3())
.SharedContext(CC => {
CC.Data = new RequiredData();
CC.ServerController = GetServerController();
});
}
private IServerController GetServerController()
{
// return proper instance of server controller
throw new NotImplementedException();
}
}
Requires this extension method / function...
public static class XMultiCommand
{
// How can I have a shared context like this for all Commands of the group?
public static MultiCommand SharedContext(this MultiCommand mc, Action<CommandContext> CallBack)
{
var cc = new CommandContext();
CallBack(cc);
mc.SharedContext = cc;
return mc;
}
}
Finally, these changes to MultiCommand
public class MultiCommand
{
private System.Collections.Generic.List<ICommand> list;
public List<ICommand> Commands { get { return list; } }
public CommandContext SharedContext { get; set; }
public MultiCommand() { }
public MultiCommand(System.Collections.Generic.List<ICommand> list)
{
this.list = list;
}
public MultiCommand Add(ICommand cc)
{
list.Add(cc);
return this;
}
internal void Execute()
{
throw new NotImplementedException();
}
public static MultiCommand New()
{
return new MultiCommand();
}
}
Cool Things Happen Using Functional Styles
Re-usability soars!
Hyper focus on Single Responsibility concerns
Composition becomes the Norm
Code Maintenance becomes simple
Intellisense becomes your built-in API (just use code commenting)
No radical OOP design patterns are needed
Fluent code becomes very enjoyable to work with
Nested / Decorated Functions are much more easy to imagine and implement
You will never repeat youerself
The Open/Closed principal becomes your religion
Code is now always Clear, Complete and Concise
Some even say no interfaces are needed any longer
In your case, going with injecting context through constructor is fine as mentioned by others. But in general, I would go with injecting the context through method parameters instead:
public class Command1: BaseCommand
{
//inject as parameter instead
public void Execute(Context ctx)
{
}
}
The reasons are:
The context should be managed by CommandGroup so that we have better encapsulation.
The CommandGroup is responsible for executing its list of commands so that it's possible for the CommandGroup to pass to each Command only the parameters each Command really needs, these parameters may be constructed at runtime (maybe by previous Commands) so that it's not possible to pass in these objects as the time we construct the list of commands. Therefore, it's easier to reuse Command and also simplify unit testing these Commands as we don't need to construct the whole context object in unit tests.
Maybe you don't need to care about these things at the moment, but method injection gives more flexibility. If you have worked with some frameworks in .NET, you would see something similar like OwinContext, FilterContext,.. they are passed as parameters and contain relevant information for that context.
In my opinion, your case is not a good fit for Command pattern. A Command represents a user request (action) and these objects could be created dynamically at runtime, but you're predefining your Commands at coding time.
What you're trying to do looks like owin middleware or asp.net web api message handler which are http://www.dofactory.com/net/chain-of-responsibility-design-pattern
And what about changing your approach? I did an architecture for DDD recently and executing a commad implies atomic operation (retrieve aggregate root from persitence, apply domain rules and pesist the aggregate) so I do not in needed of a share context and can batch multiple commands whithout worries.
Here you have an cqrs architecture that use command pattern with the above strategy I posted.
My 0.02:
1) The MultiCommand class looks like a Composite pattern.
You may want to add a GetParentCommand() method at the base command class and add an AddChildCommand() method at the MultiCommand class, which set every children's parent.
Then the children commands could get the context object from its parent. (Context object should also be defined in base class. And it may be of generic type.)
edit:
abstract class BaseCommand<T> : ICommand
{
public T Context { get; set; }
public BaseCommand Parent { get; set; }
}
class MultiCommand : BaseCommand
{
public void AddChildCommand(BaseCommand command)
{
command.parent = this; // we can get parent's context from children now
// put the command in an internal list
}
}
var commandsGroup = new MultiCommand();
commandsGroup.AddChildCommand(new Command1());
commandsGroup.AddChildCommand(new Command2());
commandsGroup.AddChildCommand(new Command3());
commandsGroup.Execute()
2) We may create a global singleton context object. In MultiCommand's Execute function, we could set the current context object before executing children's Execute function. Then child command could just access the singleton context object. And after all children's execution, the MultiCommand could reset the context. (The context is actually a stack here.)
edit:
abstract class BaseCommand : ICommand
{
// it could be put anywhere else as long as it can be accessed in command's Execute
// it can also be a stack
public static CommandContext Context {get; set;}
}
class MutliCommand : BaseCommand
{
public void Execute()
{
// do something to BaseCommand.Context
ChildCommand.Execute();
// do something to BaseCommand.Context
}
}
class ChildComand: BaseCommand
{
void Execute()
{
// do something with BaseCommand.Context
}
}
Another option is to put the context object as a parameter of the Execute function:
class MultiCommand : BaseCommand
{
void Execute(CommandContext context)
{
Children.Execute(context);
}
}
I know this question might look like it's a duplicate but please let me explain.
So I created several components that use a pluggable architecture, basically I can freely add new implementations and they will be injected and processed automatically for me. This is really handy in several scenarios.
I'm going to talk about the simplest one, validating components.
One of the reasons to use a design like this is that I like to expose my roles explicitly as explained by Udi Dahan
Basically I have code like this:
public interface IValidatorRuner
{
void Run<TTarget>(TTarget target);
}
public class ValidatorRunenr : IValidatorRuner
{
private readonly IServiceLocator _serviceLocator;
public ValidatorRunenr(IServiceLocator serviceLocator)
{
_serviceLocator = serviceLocator;
}
public void Run<TTarget>(TTarget target)
{
// this is the dynamic/pluggable phase
// is this an antipattern???
var foundValdiators = _serviceLocator.GetAllInstances<IValidator<TTarget>>();
foreach (var valdiator in foundValdiators)
{
valdiator.IsSatisfiedBy(target);
}
}
}
This code lets me expose my validation rules explicitly like this:
//this will allow me to create validators in this way
//and they will be automatically injected and resolved for me
//(easy, to read, easy to write, easy to test, pff I could even smoke this validator easily)
public class OneValdiationRuleExplicitlyExposedAndEasyToTest : IValidator<Person>
{
public bool IsSatisfiedBy(Person target)
{
return target.Age > 18;
}
}
public class Person
{
public int Age { get; set; }
}
public interface IValidator<TTarget>
{
bool IsSatisfiedBy(TTarget target);
}
And I will use this code like this:
//usage
public class SomeCommandHandler
{
private readonly IValidatorRuner _validatorRuner;
public SomeCommandHandler(IValidatorRuner validatorRuner)
{
_validatorRuner = validatorRuner;
}
public void SomeMethod()
{
_validatorRuner.Run(new Person{Age = 16});
}
}
Validation was just one example, I also use it to fire domain events and to run pipelines and filters in the same pluggable way
Is using the service locator in this way an anti-pattern?
I know I might be hiding some dependencies, but the thing is that the dependencies are dynamically injected and discovered when the application initializes (Composition root)
Your thoughts will be greatly appreciated
In my opinion, the primary issue with your code sample is that the service locator is itself injected into the implementation of ValidatorRunner. For me, this is an anti-pattern, but perhaps not the one you're asking about.
Any answer I might give boils down to the capabilities of your service locator implementation. But for sure it should not be passed into the constructor of your class. Instead, the service locator should itself pass these things in when you ask it for an implementation of "IValidatorRuner"
As an example, you can inject a factory that knows how to load the dynamic validator instances for a given type.
If anyone is interested, I found a way to remove the ServiceLocator in my objects and still dynamically load/discover dependencies at run time.
The way I solved it was by registering my components in my DI container in the following way (using the Mediator pattern):
Binding mediator (shortbus) with/to ninject
var kernel = new StandardKernel();
kernel.Bind(x => x.FromThisAssembly()
.SelectAllClasses()
.InheritedFromAny(
new[]
{
typeof(IValidatorRunner<>)
})
.BindDefaultInterfaces());
And my final implementation looks like:
public interface IValidatorRuner<in TTarget>
{
void Run(TTarget target);
}
public class ValidatorRunenr<TTarget> : IValidatorRuner<TTarget>
{
private readonly IEnumerable<IValidator<TTarget>> _validators;
public ValidatorRunenr(IEnumerable<IValidator<TTarget>> validators)
{
_validators = validators;
}
public void Run(TTarget target)
{
foreach (var valdiator in _validators)
{
valdiator.IsSatisfiedBy(target);
}
}
}
Usage
//usage
public class SomeCommandHandler
{
private readonly IValidatorRuner<OneValdiationRuleExplicitlyExposedAndEasyToTest> _validatorRuner;
public SomeCommandHandler(IValidatorRuner<OneValdiationRuleExplicitlyExposedAndEasyToTest> validatorRuner)
{
_validatorRuner = validatorRuner;
}
public void SomeMethod()
{
_validatorRuner.Run(new Person{Age = 16});
}
}
In few words, by registering an opened generic type, my container resolves any call to that type creating a concrete-closed-generic-type instance at runtime for me.
As you can see in the usage, I do not have to create a specific concrete-closed-generic type of IValidatorRunner<OneValdiationRuleExplicitlyExposedAndEasyToTest> because the container creates one for me.
And there you go, now I'm happy because I removed the service locator from my domain objects =)
I built a .NET ASMX web service connecting to an SQL Server database. There is a web service call GetAllQuestions().
var myService = new SATService();
var serviceQuestions = myService.GetAllQuestions();
I saved the result of GetAllQuestions to GetAllQuestions.xml in the local application folder
Is there any way to fake the web service call and use the local xml result?
I just want to take the contents of my entire sql table and have the array of objects with correlating property names automatically generated for me just like with LINQ to SQL web services.
Please keep in mind that I am building a standalone Monotouch iPhone application.
Use dependency injection.
//GetSATService returns the fake service during testing
var myService = GetSATService();
var serviceQuestions = myService.GetAllQuestions();
Or, preferably, in the constructor for the object set the SATService field (so the constructor requires the SATService to be set. If you do this, it will be easier to test.
Edit: Sorry, I'll elaborate here. What you have in your code above is a coupled dependency, where your code creates the object it is using. Dependency injection or the Inversion of Control(IOC) pattern, would have you uncouple that dependency. (Or simply, don't call "new" - let something else do that - something you can control outside the consumer.)
There are several ways to do this, and they are shown in the code below (comments explain):
class Program
{
static void Main(string[] args)
{
//ACTUAL usage
//Setting up the interface injection
IInjectableFactory.StaticInjectable = new ConcreteInjectable(1);
//Injecting via the constructor
EverythingsInjected injected =
new EverythingsInjected(new ConcreteInjectable(100));
//Injecting via the property
injected.PropertyInjected = new ConcreteInjectable(1000);
//using the injected items
injected.PrintInjectables();
Console.WriteLine();
//FOR TESTING (normally done in a unit testing framework)
IInjectableFactory.StaticInjectable = new TestInjectable();
EverythingsInjected testInjected =
new EverythingsInjected(new TestInjectable());
testInjected.PropertyInjected = new TestInjectable();
//this would be an assert of some kind
testInjected.PrintInjectables();
Console.Read();
}
//the inteface you want to represent the decoupled class
public interface IInjectable { void DoSomething(string myStr); }
//the "real" injectable
public class ConcreteInjectable : IInjectable
{
private int _myId;
public ConcreteInjectable(int myId) { _myId = myId; }
public void DoSomething(string myStr)
{
Console.WriteLine("Id:{0} Data:{1}", _myId, myStr);
}
}
//the place to get the IInjectable (not in consuming class)
public static class IInjectableFactory
{
public static IInjectable StaticInjectable { get; set; }
}
//the consuming class - with three types of injection used
public class EverythingsInjected
{
private IInjectable _interfaceInjected;
private IInjectable _constructorInjected;
private IInjectable _propertyInjected;
//property allows the setting of a different injectable
public IInjectable PropertyInjected
{
get { return _propertyInjected; }
set { _propertyInjected = value; }
}
//constructor requires the loosely coupled injectable
public EverythingsInjected(IInjectable constructorInjected)
{
//have to set the default with property injected
_propertyInjected = GetIInjectable();
//retain the constructor injected injectable
_constructorInjected = constructorInjected;
//using basic interface injection
_interfaceInjected = GetIInjectable();
}
//retrieves the loosely coupled injectable
private IInjectable GetIInjectable()
{
return IInjectableFactory.StaticInjectable;
}
//method that consumes the injectables
public void PrintInjectables()
{
_interfaceInjected.DoSomething("Interface Injected");
_constructorInjected.DoSomething("Constructor Injected");
_propertyInjected.DoSomething("PropertyInjected");
}
}
//the "fake" injectable
public class TestInjectable : IInjectable
{
public void DoSomething(string myStr)
{
Console.WriteLine("Id:{0} Data:{1}", -10000, myStr + " For TEST");
}
}
The above is a complete console program that you can run and play with to see how this works. I tried to keep it simple, but feel free to ask me any questions you have.
Second Edit:
From the comments, it became clear that this was an operational need, not a testing need, so in effect it was a cache. Here is some code that will work for the intended purpose. Again, the below code is a full working console program.
class Program
{
static void Main(string[] args)
{
ServiceFactory factory = new ServiceFactory(false);
//first call hits the webservice
GetServiceQuestions(factory);
//hists the cache next time
GetServiceQuestions(factory);
//can refresh on demand
factory.ResetCache = true;
GetServiceQuestions(factory);
Console.Read();
}
//where the call to the "service" happens
private static List<Question> GetServiceQuestions(ServiceFactory factory)
{
var myFirstService = factory.GetSATService();
var firstServiceQuestions = myFirstService.GetAllQuestions();
foreach (Question question in firstServiceQuestions)
{
Console.WriteLine(question.Text);
}
return firstServiceQuestions;
}
}
//this stands in place of your xml file
public static class DataStore
{
public static List<Question> Questions;
}
//a simple question
public struct Question
{
private string _text;
public string Text { get { return _text; } }
public Question(string text)
{
_text = text;
}
}
//the contract for the real and fake "service"
public interface ISATService
{
List<Question> GetAllQuestions();
}
//hits the webservice and refreshes the store
public class ServiceWrapper : ISATService
{
public List<Question> GetAllQuestions()
{
Console.WriteLine("From WebService");
//this would be your webservice call
DataStore.Questions = new List<Question>()
{
new Question("How do you do?"),
new Question("How is the weather?")
};
//always return from your local datastore
return DataStore.Questions;
}
}
//accesses the data store for the questions
public class FakeService : ISATService
{
public List<Question> GetAllQuestions()
{
Console.WriteLine("From Fake Service (cache):");
return DataStore.Questions;
}
}
//The object that decides on using the cache or not
public class ServiceFactory
{
public bool ResetCache{ get; set;}
public ServiceFactory(bool resetCache)
{
ResetCache = resetCache;
}
public ISATService GetSATService()
{
if (DataStore.Questions == null || ResetCache)
return new ServiceWrapper();
else
return new FakeService();
}
}
Hope this helps. Good luck!
when you say fake the call, are you just testing the client side?
you could use fiddler, intercept the request and return the local xml file to the client. No messing around with your client code then.
To elaborate on Audie's answer
Using DI would get you what you want. Very simply you would create an interface that your real object and your mock object both implement
public interface IFoo
{}
Then you would have your GetSATService method return either a MockSATSerivce or the real SATService object based on your needs.
This is where you would use a DI container (some object that stores interface to concrete type mappings) You would bootstrap the container with the types you want. So, for a unit test, you could contrstruct a mock container that registers the MockSATService as the implementer of the IFoo interface.
Then you would as the container for the concrete type but interface
IFoo mySATService = Container.Resolve<IFoo>();
Then at runtime you would just change out the container so that it bootstraps with the runtime types instead of the mock types but you code would stay the same (Because you are treating everything as IFoo instead SATService)
Does that make sense?
Over time I found that an interesting way to do this is by extracting an interface and creating a wrapper class. This adapts well to a IoC container and also works fine without one.
When testing, create the class passing a fake service. When using it normally, just call the empty constructor, which might simply construct a provider or resolve one using a config file.
public DataService : IDataService
{
private IDataService _provider;
public DataService()
{
_provider = new RealService();
}
public DataService(IDataService provider)
{
_provider = provider;
}
public object GetAllQuestions()
{
return _provider.GetAllQuestions();
}
}