I have just begun exploring the design patterns and implementation of Web APIs.
I have a scenario where one single API requests to a set of APIs in sequence based on a string value.
Eg: let's say I have an API called StartAPI.
This might send request to a subset of APIs (let's call it API_X, API_Y, API_Z, API_T, API_U) based on given string.
Let's assume the below:
If i pass "string1" or "string2" to StartAPI then it should call API_X, API_Z.
If i pass "string3" it calls API_X, API_Z, API_T.
If i pass "string4" it calls all APIs
API_X, API_Z, API_T, API_Y, API_U.
What design pattern can I follow in this case to minimise the if else conditions?
It looks like that Chain of Responsibity pattern is way to go. As wiki says:
the chain-of-responsibility pattern is a behavioral design pattern
consisting of a source of command objects and a series of processing
objects.1 Each processing object contains logic that defines the
types of command objects that it can handle; the rest are passed to
the next processing object in the chain. A mechanism also exists for
adding new processing objects to the end of this chain.
So let me show an example how code would look like. Let's start from classes which define API:
public class BaseApi
{
public virtual string Get()
{
return "";
}
}
and its concrete implementations:
public class ApiX : BaseApi
{
public override string Get()
{
return "Api_X";
}
}
public class ApiZ : BaseApi
{
public override string Get()
{
return "Api_X";
}
}
public class ApiT : BaseApi
{
public override string Get()
{
return "Api_T";
}
}
Then this is Parameter class:
public class Parameter
{
public string Parameter_1 { get; set; }
}
Then we need some place where we will store all API's that should be called. I think, we can create some very simple factory. This factory will have just one overridable method:
public abstract class ApiSimpleFactory
{
public abstract IEnumerable<BaseApi> GetAll();
}
and its concrete implementations:
public class ApiXZSimpleFactory : ApiSimpleFactory
{
public override IEnumerable<BaseApi> GetAll() =>
new List<BaseApi>()
{
new ApiX(),
new ApiZ(),
};
}
public class ApiXZTSimpleFactory : ApiSimpleFactory
{
public override IEnumerable<BaseApi> GetAll() =>
new List<BaseApi>()
{
new ApiX(),
new ApiZ(),
new ApiT(),
};
}
Now, we are ready to implementat Chain Of Responsibity pattern:
public abstract class ApiHandler
{
private protected abstract IEnumerable<string> ParameterOptions { get; }
private ApiHandler _nextApiHandler;
public void SetSuccessor(ApiHandler nextVehicleHandler)
{
_nextApiHandler = nextVehicleHandler;
}
public virtual ApiSimpleFactory Execute(Parameter parameter)
{
if (_nextApiHandler != null)
return _nextApiHandler.Execute(parameter);
return null;
}
}
and its concrete implementations:
public class XZApiHandler : ApiHandler
{
private protected override IEnumerable<string> ParameterOptions =>
new List<string> { "string1", "string2" };
public override ApiSimpleFactory Execute(Parameter parameter)
{
if (ParameterOptions.Contains(parameter.Parameter_1))
return new ApiXZSimpleFactory();
return base.Execute(parameter);
}
}
public class XZTApiHandler : ApiHandler
{
private protected override IEnumerable<string> ParameterOptions =>
new List<string> { "string3" };
public override ApiSimpleFactory Execute(Parameter parameter)
{
if (ParameterOptions.Contains(parameter.Parameter_1))
return new ApiXZTSimpleFactory();
return base.Execute(parameter);
}
}
And now we can execute our code:
ApiHandler chain = new XZApiHandler();
ApiHandler xztApiHandler = new XZTApiHandler();
chain.SetSuccessor(xztApiHandler);
Parameter parameter = new Parameter { Parameter_1 = "string3" };
ApiSimpleFactory apiFactory = chain.Execute(parameter);
IEnumerable<BaseApi> apiToBeExecuted = apiFactory.GetAll();
I currently working on an application that will act differently based on userInput. So I think about the Strategy Pattern. Below is my implementation:
I have some business logic:
interface IBusinessLogic
{
void DoBusinessLogic();
}
class TypeABusinessLogic : IBusinessLogic
{
public void DoBusinessLogic()
{
Console.WriteLine("Do Business Logic for Type A");
}
}
class TypeBBusinessLogic : IBusinessLogic
{
public void DoBusinessLogic()
{
Console.WriteLine("Do Business Logic for Type B");
}
}
And, also some application logic:
interface IApplicationLogic
{
void DoApplicationLogic();
}
class TypeAApplicationLogic : IApplicationLogic
{
public void DoApplicationLogic()
{
Console.WriteLine("Do Application Logic for Type A");
}
}
class TypeBApplicationLogic : IApplicationLogic
{
public void DoApplicationLogic()
{
Console.WriteLine("Do Application Logic for Type B");
}
}
Now, my strategies need to do both business logic and application logic
interface IStrategy
{
void DoWork();
}
abstract class StrategyBase : IStrategy
{
private IBusinessLogic _businessLogic;
private IApplicationLogic _applicationLogic;
protected StrategyBase(IBusinessLogic businessLogic, IApplicationLogic applicationLogic)
{
_businessLogic = businessLogic;
_applicationLogic = applicationLogic;
}
public void DoWork()
{
_businessLogic.DoBusinessLogic();
_applicationLogic.DoApplicationLogic();
}
}
class TypeAStrategy : IStrategy
{
public TypeAStrategy(TypeABussinessLogic businessLogic, TypeAApplicationLogic applicationLogic) : base(businessLogic, applicationLogic)
{}
}
class TypeBStrategy : IStrategy
{
public TypeBStrategy(TypeBBussinessLogic businessLogic, TypeBApplicationLogic applicationLogic) : base(businessLogic, applicationLogic)
{}
}
Now is my Context class
class Context
{
private Func<string, IStrategy> _strategyFactory;
public Context(Func<string, IStrategy> strategyFactory)
{
_strategyFactory = strategyFactory;
}
public void Run()
{
string userInput = GetUserInput(); //"TypeA" or "TypeB"
IStrategy strategy = _strategyFactory(userInput);
strategy.DoWork();
}
}
Here is my DI builder code:
var builder = new ContainerBuilder();
builder.RegisterType<TypeAStrategy>().As<IStrategy>().Keyed<IStrategy>("TypeA");
var builder = new ContainerBuilder();
builder.RegisterType<TypeBStrategy>().As<IStrategy>().Keyed<IStrategy>("TypeB");
builder.Register<Func<string, IStrategy>>( c =>
{
var componentContext = c.Resolve<IComponentContext>();
return (key) =>
{
IStrategy stategy = componentContext.ResolveKeyed<IStrategy >(key);
return stategy;
};
});
The problem I can see here is my strategies (TypeAStrategy, TypeBStrategy) depend directly on concrete class (TypeABusinessLogic,TypeAApplicationLogic,TypeBBusinessLogic, TypeBApplicationLogic), which is not good. I can't mock these dependencies in unit test.
If I let my strategies depend on interfaces, I dont know how to implement DI container to resolve dependencies (Notes: I currently using Autofac, but I can use any other DI containers )
Please advise.
So I thought of a few ways to approach this, but I think the cleanest way is to just introduce some token interfaces. A token interface is one which doesn't add any properties or functionality. For instance:
interface IBusinessLogic
{
void DoBusinessLogic();
}
interface ITypeABusinessLogic : IBusinessLogic { }
interface ITypeBBusinessLogic : IBusinessLogic { }
interface IApplicationLogic
{
void DoApplicationLogic();
}
interface ITypeAApplicationLogic : IApplicationLogic { }
interface ITypeBApplicationLogic : IApplicationLogic { }
Next we adjust the classes to implement the relevant token interface:
class TypeABusinessLogic : ITypeABusinessLogic
{
public virtual void DoBusinessLogic()
{
Console.WriteLine("Do Business Logic for Type A");
}
}
class TypeBBusinessLogic : ITypeBBusinessLogic
{
public virtual void DoBusinessLogic()
{
Console.WriteLine("Do Business Logic for Type B");
}
}
class TypeAApplicationLogic : ITypeAApplicationLogic
{
public void DoApplicationLogic()
{
Console.WriteLine("Do Application Logic for Type A");
}
}
class TypeBApplicationLogic : ITypeBApplicationLogic
{
public void DoApplicationLogic()
{
Console.WriteLine("Do Application Logic for Type B");
}
}
We can similarly create mock classes by implementing the relevant token interface:
class MockTypeABusinessLogic : ITypeABusinessLogic
{
public void DoBusinessLogic()
{
Console.WriteLine("[Mock] Do Business Logic for Type A");
}
}
class MockTypeBBusinessLogic : ITypeBBusinessLogic
{
public void DoBusinessLogic()
{
Console.WriteLine("[Mock] Do Business Logic for Type B");
}
}
class MockTypeAApplicationLogic : ITypeAApplicationLogic
{
public void DoApplicationLogic()
{
Console.WriteLine("[Mock] Do Application Logic for Type A");
}
}
class MockTypeBApplicationLogic : ITypeBApplicationLogic
{
public void DoApplicationLogic()
{
Console.WriteLine("[Mock] Do Application Logic for Type B");
}
}
I also modified the IStrategy interface to make injection with Unity a little easier, giving each strategy a Name property (you don't need to do this):
interface IStrategy
{
string Name { get; }
void DoWork();
}
abstract class StrategyBase : IStrategy
{
private IBusinessLogic _businessLogic;
private IApplicationLogic _applicationLogic;
public string Name { get; private set; }
protected StrategyBase(String name, IBusinessLogic businessLogic, IApplicationLogic applicationLogic)
{
this.Name = name;
_businessLogic = businessLogic;
_applicationLogic = applicationLogic;
}
public void DoWork()
{
_businessLogic.DoBusinessLogic();
_applicationLogic.DoApplicationLogic();
}
}
class TypeAStrategy : StrategyBase
{
public TypeAStrategy(String name, ITypeABusinessLogic businessLogic, ITypeAApplicationLogic applicationLogic) : base(name, businessLogic, applicationLogic)
{ }
}
class TypeBStrategy : StrategyBase
{
public TypeBStrategy(String name, ITypeBBusinessLogic businessLogic, ITypeBApplicationLogic applicationLogic) : base(name, businessLogic, applicationLogic)
{ }
}
Using Unity I wrote the following program to test the registrations:
class Context
{
private Dictionary<string, IStrategy> _strategyFactory = new Dictionary<string, IStrategy>();
public Context(IStrategy[] strategies)
{
foreach (var s in strategies)
{
_strategyFactory.Add(s.Name, s);
}
}
public void Run()
{
string userInput = "TypeA";
IStrategy strategy = _strategyFactory[userInput];
strategy.DoWork();
userInput = "TypeB";
strategy = _strategyFactory[userInput];
strategy.DoWork();
}
}
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Mock DI Example: ");
UnityContainer ioc = new UnityContainer();
ioc.RegisterType<ITypeABusinessLogic, MockTypeABusinessLogic>();
ioc.RegisterType<ITypeAApplicationLogic, MockTypeAApplicationLogic>();
ioc.RegisterType<ITypeBBusinessLogic, MockTypeBBusinessLogic>();
ioc.RegisterType<ITypeBApplicationLogic, MockTypeBApplicationLogic>();
ioc.RegisterType<IStrategy, TypeAStrategy>("TypeA", new InjectionConstructor("TypeA", typeof(ITypeABusinessLogic), typeof(ITypeAApplicationLogic)));
ioc.RegisterType<IStrategy, TypeBStrategy>("TypeB", new InjectionConstructor("TypeB", typeof(ITypeBBusinessLogic), typeof(ITypeBApplicationLogic)));
Context c = ioc.Resolve<Context>();
c.Run();
Console.WriteLine("\nUnmocked DI Example: ");
ioc = new UnityContainer();
ioc.RegisterType<ITypeABusinessLogic, TypeABusinessLogic>();
ioc.RegisterType<ITypeAApplicationLogic, TypeAApplicationLogic>();
ioc.RegisterType<ITypeBBusinessLogic, TypeBBusinessLogic>();
ioc.RegisterType<ITypeBApplicationLogic, TypeBApplicationLogic>();
ioc.RegisterType<IStrategy, TypeAStrategy>("TypeA", new InjectionConstructor("TypeA", typeof(ITypeABusinessLogic), typeof(ITypeAApplicationLogic)));
ioc.RegisterType<IStrategy, TypeBStrategy>("TypeB", new InjectionConstructor("TypeB", typeof(ITypeBBusinessLogic), typeof(ITypeBApplicationLogic)));
c = ioc.Resolve<Context>();
c.Run();
Console.WriteLine("\nPress enter to exit...");
Console.ReadLine();
}
And here was my output:
Mock DI Example:
[Mock] Do Business Logic for Type A
[Mock] Do Application Logic for Type A
[Mock] Do Business Logic for Type B
[Mock] Do Application Logic for Type B
Unmocked DI Example:
Do Business Logic for Type A
Do Application Logic for Type A
Do Business Logic for Type B
Do Application Logic for Type B
Press enter to exit...
This isn't the only way to solve the problem, but I think this most directly matches how you have structured your code in the OP. Hope this helps :)
EDIT: Here is one alternative to the above which I think you should consider. It will cut down on your object and interface hierarchy quite a bit. NOTE: you'll need to make the StrategyBase class not abstract, and expose the constructor as public.
Console.WriteLine("\nAlternative DI Example: ");
ioc = new UnityContainer();
ioc.RegisterType<IBusinessLogic, TypeABusinessLogic>("TypeA");
ioc.RegisterType<IApplicationLogic, TypeAApplicationLogic>("TypeA");
ioc.RegisterType<IStrategy, StrategyBase>("TypeA", new InjectionConstructor("TypeA", new ResolvedParameter<IBusinessLogic>("TypeA"), new ResolvedParameter<IApplicationLogic>("TypeA") ));
ioc.RegisterType<IBusinessLogic, TypeBBusinessLogic>("TypeB");
ioc.RegisterType<IApplicationLogic, TypeBApplicationLogic>("TypeB");
ioc.RegisterType<IStrategy, StrategyBase>("TypeB", new InjectionConstructor("TypeB", new ResolvedParameter<IBusinessLogic>("TypeB"), new ResolvedParameter<IApplicationLogic>("TypeB")));
c = ioc.Resolve<Context>();
c.Run();
Since your classes and the token interfaces don't actually provide you any functionality, they only serve as a means of differentiating the specific implementations. But DI containers already have a simple means of doing this: strings. In Unity you can use the same string for different types, like above. You can use this to delineate which specific implementations go together. This is my recommendation :)
What i'm trying to accomplish is to have a single wcf service that has (for example) an Insert(ICommand command) method and can resolve a generic service that knows how to insert the underling object type.
Where's my (poor) attempt on a sandbox project.
Besides other flaws, this services allow to attempt to insert any ICommand.
I'm relative new Unit user and i was wondering if someone has a better way to accomplish this.
class Program
{
static void Main(string[] args)
{
var cmd = new SingleCommand();
var cmd2 = new DoubleCommand();
var s = new MyWcfService();
s.Insert(cmd);
s.Insert(cmd2);
Console.ReadKey();
}
}
public interface ICommand { }
public interface ICommandService
{
void Insert(ICommand command);
}
public interface ICommandService<in T> : ICommandService where T : ICommand
{
void Insert(T command);
}
public class SingleCommand : ICommand { }
public class DoubleCommand : ICommand { }
public class SingleCommandService : ICommandService<SingleCommand>
{
public void Insert(SingleCommand singleCommand)
{
Console.WriteLine("Inserted a SingleCommand");
}
void ICommandService.Insert(ICommand command)
{
Insert((SingleCommand)command);
}
}
public class DoubleCommandService : ICommandService<DoubleCommand>
{
public void Insert(DoubleCommand doubleCommand)
{
Console.WriteLine("Inserted a DoubleCommand");
}
void ICommandService.Insert(ICommand command)
{
Insert((DoubleCommand)command);
}
}
public static class Config
{
public static UnityContainer Container = new UnityContainer();
static Config()
{
Container.RegisterType<ICommandService, SingleCommandService>(typeof(SingleCommand).Name);
Container.RegisterType<ICommandService, DoubleCommandService>(typeof(DoubleCommand).Name);
}
}
public class MyWcfService
{
public void Insert(ICommand command)
{
var foo = Config.Container.Resolve<ICommandService>(command.GetType().Name);
foo.Insert(command);
}
}
If you really don't have a service that can be invoked for all ICommand, then you shouldn't offer that in its contract. An easy way around this is to extend the ICommand interface into something like IServiceCommand, and have those ICommand which are supported implement IServiceCommand instead, and tie your service contract instead to that interface. This allows your concrete classes to be used in any method which expects an ICommand, but your service still only service those ICommand which are also IServiceCommand.
I'm trying to figure out how to register the following decorator scenario with Castle Windsor. I have the following interface:
public interface ICalculate<T> where T : class
{
void Calculate(T value);
}
And a couple of implementations where the last one is a decorator.
public class FooCalculator : ICalculate<Foo>
{
public void Calculate(Foo value)
{
// do something here with the value..
}
}
public class BarCalculator : ICalculate<Bar>
{
public void Calculate(Bar value)
{
// do something else here....
}
}
public class CalculatorDecorator<T> : ICalculate<T> where T : class
{
private readonly ICalculate<T> _calculator;
public CalculatorDecorator(ICalculate<T> calculator)
{
_calculator = calculator;
}
public void Calculate(T value)
{
// do for example some logging...
_calculator.Calculate(value);
}
}
This is my registration code
container.Register(Classes.FromAssembly()
.BasedOn(typeof(ICalculate<>))
.WithService.Base());
When i request one of the implementations by their generic interface I want Windsor to resolve the CalculatorDecorator with the requested implementation injected in the constructor.
// I would like calculator to be CalculatorDecorator<Foo> in
// this case but it is FooCalculator.
var calculator = container.Resolve<ICalculate<Foo>>();
// The same goes for this one...
var calculator = containr.Resolve<ICalculate<Bar>>();
Thanks in advance!
Edit:
It works if I do like this
container.Register(Component.For<ICalculate<Foo>>()
.ImplementedBy<CalculatorDecorator<Foo>>(),
Component.For<ICalculate<Foo>>()
.ImplementedBy<FooCalculator>());
container.Register(Component.For<ICalculate<Bar>>()
.ImplementedBy<CalculatorDecorator<Bar>>(),
Component.For<ICalculate<Bar>>()
.ImplementedBy<BarCalculator>());
But I would prefer to register all components if it's possible.
container.Register(AllTypes.FromAssembly()
.BasedOn(typeof(ICalculate<>))
.WithService.Base());
Did you try this? We had a similar situation and this worked for us.
UPDATE
I don't think this is possible because you'll create a circular dependency.
I did get it working like following:
Registration
var container = new WindsorContainer();
container.Register(Component.For(typeof(IDecorator<>)).ImplementedBy(typeof(CalculatorDecorator<>)));
container.Register(AllTypes.FromThisAssembly()
.BasedOn(typeof (ICalculate<>))
.WithService.Base());
var fc = container.Resolve<IDecorator<Foo>>();
var bc = container.Resolve<IDecorator<Bar>>();
Interfaces:
public interface ICalculate<T> where T : class
{
void Calculate(T value);
}
public interface IDecorator<T> : ICalculate<T> where T : class
{
}
Implementation:
public class FooCalculator : ICalculate<Foo>
{
public void Calculate(Foo value)
{
// do something here with the value..
}
}
public class BarCalculator : ICalculate<Bar>
{
public void Calculate(Bar value)
{
// do something else here....
}
}
public class CalculatorDecorator<T>: IDecorator<T> where T : class
{
private readonly ICalculate<T> _calculator;
public CalculatorDecorator(ICalculate<T> calculator)
{
_calculator = calculator;
}
public void Calculate(T value)
{
// do for example some logging...
_calculator.Calculate(value);
}
}
I have two data structure classes (this is a simplified version of my code)
Animal: Has one property “int Age”
Person: Has one property “DateTime Birthday”
What I am trying to accomplish is to compile “Uploading” (persisting to database), which is common across all different data structure classes.
So mainly my goal is to have a small Upload method that looks like
foreach (TypeName typeName in Enum.GetValues(typeof(TypeName)))
{
IDataPopulator populator =
new DataFactory().CreateDataPopulator(typeName);
populator.Populate(string.Empty);
}
But the problem is that, populator returns an object instances of different types, which I am having trying to encapsulate since they have no common properties.
(IDataPopulator.TResult Populate(string data) in the code below)
Is there a way to get around this? Or does Strategy pattern not fit for this kind of scenario?
Here is the code I’ve been working with
public class Program
{
public static void Main()
{
foreach (TypeName typeName in Enum.GetValues(typeof(TypeName)))
{
IDataPopulator populator = new DataFactory().CreateDataPopulator(typeName);
populator.Populate(string.Empty);
}
}
}
public enum TypeName { Person, Animal }
public class Person { public DateTime Birthday { get; set; } }
public class Animal { public int Age { get; set; } }
public interface IDataPopulator
{
TResult Populate(string data);
}
class AnimalDataPopulator : IDataPopulator
{
public Animal Populate(string data)
{
// create an instance of Animal using data
}
}
class PersonDataPopulator : IDataPopulator
{
public Person Populate(string data)
{
// create an instance of Person using data
}
}
public class DataFactory
{
public IDataPopulator CreateDataPopulator(TypeName typeName)
{
switch (typeName)
{
case TypeName.Person:
return new PersonDataPopulator();
case TypeName.Animal:
return new AnimalDataPopulator();
default:
throw new ArgumentOutOfRangeException("typeName");
}
}
}
public class UploadContext
{
private readonly IUploader _Uploader;
public UploadContext(IUploader uploader) { _Uploader = uploader; }
public void Upload() { _Uploader.Upload(); }
}
public interface IUploader
{
void Upload();
}
class PersonUploader : IUploader
{
private Person _Person;
public PersonUploader(Person person) { _Person = person; }
public void Upload()
{
Console.WriteLine("Uploading person...");
}
}
class AnimalUploader : IUploader
{
private Animal _Animal;
public AnimalUploader(Animal animal) { _Animal = animal; }
public void Upload()
{
Console.WriteLine("Uploading animal...");
}
}
I don't see how the Strategy pattern would fit here. The pattern is about a family of algorithms, e.g. line breaking strategies. You don't have strategies here, you have a single abstract method
TResult Populate(string data);
and several implementations of it.
I also don't understand the initial problem, maybe you want to queue several serialization operations? In that case the Command pattern is your friend.
I think what you are after is either serialization, if you are just storing blobs, or an ORM framework.