How to implement a factory that automatically finds a strategy - c#

I've asked myself this question and I'm still not done thinking about this.
What I am thinking about
When you have a strategy pattern, a lot of implementations also use a factory pattern to retrieve a specific strategy. Most factory examples on the internet make use of a switch or if statement. This works perfectly when you do not often change or add strategies. But what if the factory is used to dynamically find a strategy and the strategies are changed and added often. Then this is a full time job for the programmer. Now I have a situation where I just want to add a new strategy without having to change the factory. In other words how do you implement the factory pattern so it dynamically searches for a strategy. And how can I list all available strategies.
The problem
When I look for this on the internet I can't find a good proper solution. I am thinking about using a reflection library to do this but it is not recommended to use reflection everywhere I look. So how to implement a dynamic factory. Or is there an other pattern for this purpose?
Example
The strategies:
The factory:
public enum StrategyName { ImplementedStrategy1, ImplementedStrategy2, ImplementedStrategy3 };
public class StrategyFactory
{
public static Sniffer getInstance(StrategyName choice) {
Strategy strategy = null;
switch (choice) {
case StrategyName.ImplementedStrategy1:
strategy = new ImplementedStrategy1();
break;
case StrategyName.ImplementedStrategy2:
strategy = new ImplementedStrategy2();
break;
case StrategyName.ImplementedStrategy3:
strategy = new ImplementedStrategy3();
break;
}
return strategy;
}
}
Now how can I make this dynamic? Or why shouldn't I?

Have your ImplementedStrategy contract include a IsGoodMatch(params) method. Then you just iterate over your collection of strategies, calling IsGoodMatch on each one until you get one (or many) results, and then you use that strategy(ies).

I am not sure if this will help but here is what i am thinking.
You have
public class ImplementedStrategy1 : Strategy
{
}
public class ImplementedStrategy2 : Strategy
{
}
etc..
Then you make an attribute class [StrategyName(StrategyName.EnumValue)].
More details here https://msdn.microsoft.com/en-us/library/aa288454(v=vs.71).aspx
So, now we get
[StrategyName(StrategyName.EnumValue1)].
public class ImplementedStrategy1 : Strategy
{
}
[StrategyName(StrategyName.EnumValue2)].
public class ImplementedStrategy2 : Strategy
{
}
Then, in public static Sniffer getInstance(StrategyName choice) instead of the switch,using reflection, you get all the types that inherit from Strategy and check if the choice parameter matches the custom attribute value.
Now you just need to create a new instance for that type.
When this is done and you wish to add a new strategy, you just have to create the new class with the attribute and add a new value to the enum.
Let me know if you need any help with the implementation.

Not sure if you still need this but it can be achieved in Java as below.
public interface Strategy {
boolean isGoodMatch(StrategyName strategyName);
}
public class ImplementedStrategy1 implements Strategy {
#Override
public boolean isGoodMatch(StrategyName strategyName) {
return strategyName == StrategyName.ImplementedStrategy1;
}
}
public class ImplementedStrategy2 implements Strategy {
#Override
public boolean isGoodMatch(StrategyName strategyName) {
return strategyName == StrategyName.ImplementedStrategy2;
}
}
public class ImplementedStrategy3 implements Strategy {
#Override
public boolean isGoodMatch(StrategyName strategyName) {
return strategyName == StrategyName.ImplementedStrategy3;
}
}
public class StrategyFactory {
private List<Strategy> strategies;
public StrategyFactory(List<Strategy> strategies){
this.strategies = strategies;
}
public Strategy getInstance(StrategyName choice){
Strategy strategyChoice = null;
for (Strategy strategy: this.strategies){
if(strategy.isGoodMatch(choice))
strategyChoice = strategy;
}
return strategyChoice;
}
}
If you wanted you could use streams in the getInstance method.
public Strategy getInstance(StrategyName choice){
return strategies
.stream()
.filter(x -> x.isGoodMatch(choice))
.findFirst()
.get();
}
You can provide the list to the factory by using a DI container as mentioned above. If you are using something like Spring you could use #Autowire annotation.
http://www.baeldung.com/spring-autowire

Related

Injecting parents into composite constructors with Unity C#

I am trying to get IoC working with Unity in C# with the idea of a passing a wrapper/composite class into the children.
The top level class that composes multiple classes provides some common functionality that the composed classes require access to.
To illustrate:
// The top composite class
public class Context : IContext {
public ISomething SomethingProcessor { get; }
public IAnother AnotherProcessor { get; }
public Context(ISomething something, IAnother another) {
this.SomethingProcessor = something;
this.AnotherProcessor = processor;
}
// A function that individual classes need access to, which itself calls one of the children.
public string GetCommonData() {
return this.AnotherProcessor.GetMyData();
}
}
public class Something : ISomething {
private _wrapper;
public Something(IContext context) {
this._wrapper = context;
}
// This class has no knowledge of IAnother, and requests data from the master/top class, which knows where to look for whatever.
public void Do() {
Console.WriteLine(_wrapper.GetCommonData());
}
}
public class Another : IAnother {
public string GetMyData() {
return "Foo";
}
}
If you didn't use IoC, it's easy, as the constructor for the Context class becomes:
public Context() {
this.SomethingProcessor = new Processor(this);
this.AnotherProcessor = new Another();
}
But when you're using IoC, the idea of "this" doesn't exist yet because it is yet to be constructed by the injector. Instead what you have a is a circular dependency.
container.RegisterType<ISomething, Something>();
container.RegisterType<IAnother, Another>();
container.RegisterType<IContext, Context>();
var cxt = container.Resolve<IContext>(); // StackOverflowException
The above example has been greatly simplified to illustrate the concept. I'm struggling to find the "best practice" way of dealing with this kind of structure to enable IOC.
Factory pattern is a way construct an object based on other dependencies or logical choices.
Factory Method: "Define an interface for creating an object, but let
the classes which implement the interface decide which class to
instantiate. The Factory method lets a class defer instantiation to
subclasses" (c) GoF.
Lots of construction.. hence the name Factory Pattern
A crude code sample that could be used with DI
public class ContextFactory : IContextFactory {
_anotherProcessor = anotherProcessor;
public ContextFactory(IAnotherProcessor anotherProcessor) {
//you can leverage DI here to get dependancies
}
public IContext Create(){
Context factoryCreatedContext = new Context();
factoryCreatedContext.SomethingProcessor = new SomethingProcessor(factoryCreatedContext )
factoryCreatedContext.AnotherProcessor = _anotherProcessor;
//You can even decide here to use other implementation based on some dependencies. Useful for things like feature flags.. etc.
return context;
}
}
You can get away with this, maybe? - but there is still the cyclic reference issue here and I would never commit this kind of code.
The problem here you need to concentrate on Inversion Of Control of that GetCommonData
Your SomethingProcessor should not rely on methods in another class. This is where In Inheritance could be used but Inheritance can become very complicated very quickly.
The best way forward is to Identify the ONE thing that is needed by both or many other places and break that out into a new Dependency. That is how you Invert Control.
TIP:
Don't overdo Interfaces- Use Interfaces where you think you will be working with Polymorphism, such as a collection of different objects that must promise you they have implemented a specific method/property. Otherwise you are over using Interfaces and increasing complexity. DI doesn't have to use Interfaces it can be a concrete implementation. Interfaces on Repositories are a good use since you can switch Databases out easily but Interfaces a factory like this is not really needed.
I don't know the name of this pattern, or even if it is a bad or good practice, but you can solve your problem of "double-binding" by creating a method to bind the "IContext", instead of doing it in the constructor.
For instance,
1) ISomething has a void BindContext(IContext context) method
2) You implement it as such :
class Something : ISomething
{
IContext _wrapper;
// ... nothing in constructor
public void BindContext(IContext context)
{
_wrapper = context;
}
}
3) Remove the IContext dependency injection in Something constructor.
And you call it from the context constructor :
public Context(ISomething something, IAnother another) {
this.SomethingProcessor = something;
this.SomethingProcessor.BindContext(this);
// same for IAnother
}
And you do the same for IAnother. You could even extract some common interface "IBindContext" to make things a beat more "DRY" (Don't Repeat yourself) and make IAnother and ISomething inherit from it.
Not tested, and again : not sure it's the best way to do such dependency design. I'll be glad if there is another answer which gives a state-of-the-art insight about this.

Factory Interface Create Method with object Argument

I have a question about creating a factory interface with a create method that can cater for accepting different argument types depending on the implementation.
To give you a bit more background, I am using dependency in injection in a project, and require stateful objects to be generated at runtime - therefore I am injecting factories (rather than the objects themselves) to create these stateful objects. The problem I have come across is that, for some interfaces, the concrete implementations simply cannot have the same constructor argument types, and so the factories that create an instance of these interfaces require almost 'dynamic' arguments to be passed to the create method.
I have been going over this for a couple of days, and the following is the best solution I could come up with (namely, passing an object to the factory create method and casting it in the concrete implementation of the factory). I am really looking for feedback from people who have come across this scenario before, to hear what they came up with, and whether or not the solution I am proposing below is acceptable.
Apologies if this is missing any information, and many thanks in advance!
//
// Types...
//
interface IDataStore
{
List<string> GetItems();
}
public class XmlDataStore : IDataStore
{
public XmlDataStore(XmlDocument xmlDoc)
{
// Initialise from XML Document...
}
public List<string> GetItems()
{
// Get Items from XML Doc...
}
}
public class SQLDataStore : IDataStore
{
public SQLDataStore(SqlConnection conn)
{
// Initialise from SqlConnection...
}
public List<string> GetItems()
{
// Get Items from Database Doc...
}
}
//
// Factories...
//
interface IDataStoreFactory
{
IDataStore Create(object obj);
}
class XmlDataStoreFactory : IDataStore
{
IDataStore Create(object obj)
{
// Cast to XmlDocument
return new XmlDataStore((XmlDocument)obj);
}
}
class SQLDataStoreFactory : IDataStore
{
IDataStore Create(object obj)
{
// Cast to SqlConnection
return new SQLDataStore((SqlConnection)obj);
}
}
Based on this comment you need one factory which produces several types of IDataStore. You could accomplish by creating a open generic factory method in the singleton factory instance.
interface IDataStore<TStoreType>
{
void SetBaseType(TStoreType obj);
List<string> GetItems();
}
interface IDataStoreFactory
{
IDataStore<TStoreType> Create<TStoreType>(TStoreType obj)
}
class DataStoreFactory : IDataStoreFactory
{
public IDataStore<TStoreType> Create<TStoreType>(TStoreType obj)
{
if (obj.GetType() == typeof(SqlConnection))
{
var store = new SQLDataStore((SqlConnection)(Object)obj);
return (IDataStore<TStoreType>)store;
}
if (obj.GetType() == typeof(XmlDocument))
{ //... and so on }
}
}
class SQLDataStore : IDataStore<SqlConnection>
{
private readonly SqlConnection connection;
public SQLDataStore(SqlConnection connection)
{
this.connection = connection;
}
public List<string> GetItems() { return new List<string>(); }
}
You can use this factory like this:
var factory = new DataStoreFactory();
var sqlDatastore = factory.Create(new SqlConnection());
var xmlDatastore = factory.Create(new XmlDocument());
Your datastore factory would become a lot less complex if you would use a DI container. You could inject the container in the factory and retrieve your instances directly from the container, which would typically build your instances from bottom to top, including there own dependencies, lifetime management and so on. But be very carefull with this approach, it is the first step to using the service locator pattern which is an anti pattern
Not really sure if I understand your question correctly but to me it sounds a little odd to have factory instances which you use for the creation of your statefull objects as you call them.
To directly answer your question: generics are your solution. You rinterface becomes an open generic abstraction:
interface IDataStore<TStoreType>
{
List<string> GetItems();
}
interface IDataStoreFactory<TStoreType>
{
IDataStore<TStoreType> Create(TStoreType obj);
}
and your factory classes will look like this:
class XmlDataStoreFactory : IDataStoreFactory<XmlDocument>
{
IDataStore<XmlDocument> Create(XmlDocument document)
{
return new XmlDataStore(document);
}
}
class SQLDataStoreFactory : IDataStoreFactory<SqlConnection>
{
IDataStore<SqlConnection> Create(SqlConnection connection)
{
return new SQLDataStore(connection);
}
}
This will work, but from the examples you give I got the impression you're using factories throughout your codebase. Maybe I'm wrong on this point, but look at your design and minimize the number of factories. Needing a factory means mixing data with behaviour and this will always, eventually, get you into trouble.
For example, let's say you have some kind of service which adds the current user to a audit log when he logs in. This service offcourse needs the current user which is a typical example of runtime data (or contextual data). But instead of:
public class AuditLogService
{
public void AddApplicationSignIn(User user)
{
//... add user to some log
}
}
I know this is not a good example because you actually wouldn't need a factory for this class, but with the next code example you'll get the point:
public class AuditLogService
{
private readonly IUserContext userContext;
public AuditLogService(IUserContext userContext)
{
this.userContext = userContext;
}
public void AddApplicationSignIn()
{
var user = this.userContext.GetCurrentUser();
//... add user to some log
}
}
So by splitting data from behaviour you rule out the need for factories. And admitted there are cases where a factory is the best solution. I do think an IDataStore is not something you need a factory for.
For a good blog on splitting data and behaviour read here

Creating different types based on some criteria

I have some code in an application that I am not really thrilled about right now. I created a few classes like so:
class Base
{
// base properties ...
}
class DerivedA : Base
{
}
class DerivedB : Base
{
}
I have a method in my application that needs to create one of these objects (with more to come in the future) based on a string property that is stored in the database. Each one of these objects gets its data from slightly different places, but the way I'm doing it right now is just a big if block and it doesn't seem very maintainable:
class BaseCreator
{
Base Create(string name)
{
if (name == "DerivedA" )
return CreateDerivedA();
else if(name == "DerivedB")
return CreateDerivedB();
}
}
What are some ways I can refactor this code to be more maintainable and make it easier to add new types in the future? I am using dependency injection (Ninject) in my application if that makes any difference.
Inheritance trees are always difficult to maintain once they grow. If you know up front that the tree will be large---seriously consider using composition instead of inheritance. Especially if you're already using a DI framework, interfaces are the way to go.
I think you should use the abstract factory pattern which solves this problem.
It provides an interface for creating families of related or dependent objects without specifying their concrete classes.
http://www.dofactory.com/Patterns/PatternAbstract.aspx
Or just a factory pattern
http://www.dotnetperls.com/factory
I will note that your if/else or switch structure is not a bad thing. The bad thing is when you have the same if/else or switch expressed multiple times.
When you have nicely decoupled your code and you are programming to the interface or abstract base rather than the concrete, know that somewhere in your application, something knows how to create the particular concrete instance that you need. This can be code, it can be configuration, it can be some container, etc. But that something has to exist. The idea is to have that something existing once.
Your approach is fine as long as this is the only method where it exists. This class' reason to exist is that it creates the concrete instances that fulfill some interface. Its reason to change is that some other concrete implementation has been added (or removed).
The general case can be solved by a bit of composition and the use of the Specification pattern:
public class Base
{
public abstract bool IsSatisfiedBy(string name);
// base properties ...
}
public class DerivedA : Base
{
public override bool IsSatisfiedBy(string name)
{
return name == "DerivedA";
}
}
public class DerivedB : Base
{
public override bool IsSatisfiedBy(string name)
{
return name == "DerivedB";
}
}
public class BaseCreator
{
private readonly IEnumerable<Base> candidates;
public BaseCreator(IEnumerable<Base> candidates)
{
this.candidates = candidates;
}
public Base Create(string name)
{
return this.candidates.First(c => c.IsSatisfiedBy(name));
}
}
If you really must use strings, you can use reflection:
object GetInstance(string typeName)
{
Type.GetType(typeName).GetConstructor(Type.EmptyTypes).Invoke(new object[0]);
}
You could also use a dictionary:
IDictionary<string, Func<object>> TypeMap = new Dictionary<string, Func<object>>()
{
{ "TypeA", () => new TypeA() },
{ "TypeB", () => new TypeB() },
{ "TypeC", () => new TypeC() },
};
object GetInstance(string typeName)
{
return TypeMap[typeName]();
}
For others landing on this page, consider using generics, if you don't have to use strings:
T CreateInstance<T>()
where T : new()
{
return new T();
}
There isn't a general answer to this question. Abstract Factory may be correct, but it all depends on what the difference is between these implementations and how you use them.
It could well be that you should be using Template, Strategy, State or any other similar pattern. Look into them, and definitely Abstract Factory, and decide on a pattern that suits your specific scenario.

Will the Factory Pattern solve my problem?

I have a requirement to create some objects that implement a given interface, where the type of concrete implementation being created is based on an Enum value.
I run into trouble when the different concrete implementations require different parameters at runtime.
This example (C#) is fine:
public enum ProductCategory
{
Modem,
Keyboard,
Monitor
}
public class SerialNumberValidatorFactory()
{
public ISerialNumberValidator CreateValidator(ProductCategory productCategory)
{
switch (productCategory)
{
case ProductCategory.Modem:
return new ModemSerialNumberValidator();
case ProductCategory.Keyboard:
return new KeyboardSerialNumberValidator();
case ProductCategory.Monitor:
return new MonitorSerialNumberValidator();
default:
throw new ArgumentException("productType", string.Format("Product category not supported for serial number validation: {0}", productCategory))
}
}
}
However, what happens if the concrete implementations have different constructor arguments? I can't pass in all the values to the SerialNumberValidatorFactory.CreateValidator() method, so how do I proceed?
I've heard the Abstract Factory pattern is supposed to solve this, but I'm not sure how to implement it properly.
You can always create a Settings container to pass to the CreateValidator method. Start with a base IValidatorSettings, then create IModemSerialNumberValidatorSettings etc, your CreateValidator could then take ProductType and IValidatorSettings arguments.
Your concrete classes for the validators would then take their IXXXValidatorSettings interface as the sole constructor argument.
Further to this you could then create an IValidatorSettings factory.
I think abstract factory is a factory that creates a factory to handle a given set of types - not sure if it would apply in your scenario.
What you are using is a Factory Method pattern, what you should use is an Abstract Factory
In abstract factory, you provide a factory class for each concrete implementation:
So your code becomes: (forgive the code, but the rationale is same)
public class SerialNumberValidatorFactory
{
public static SerialNumberValidatorFactory newInstance(
ProductCategory productCategory)
{
switch (productCategory)
{
case ProductCategory.Modem:
return new ModemValidatorFactory();
....
}
}
public abstract ISerialNumberValidator createValidator();
}
public class ModemValidatorFactory extends SerialNumberValidatorFactory
{
public ISerialNumberValidator createValidator()
{
return new ModemSerialNumberValidator("model", "number");
}
}
ISerialNumberValidator = SerialNumberValidatorFactory.newInstance(productCategory).createValidator()

C# How to generate an object implementing different interfaces dynamically at runtime?

I'm looking at how to solve a problem and I'm not even sure this might be possible at all in C# & .NET 3.5:
Say I have a limited number of interfaces, each describing a specific, non-related set of methods. Now I have a number real-world devices which each may implement just a subset of these interfaces.
During set-up of comms with these devices they will tell me which capabilities they have. I would now like to create an object implementing the interfaces (each resembling one capability of the device) so that higher up in my application architecture I'm able to:
write code against the aforementioned interfaces
test if that generated object implements a certain interface to see if certain actions are supported
I'm not sure at all which approach to use towards this problem. Any comments or approaches most welcome!
Use a mocking framework such as Moq, RhinoMocks or TypeMock Isolator
If you're looking to do something lower level, things like Castle DynamicProxy might be a good direction for you.
Try something like LinFu.DynamicObject.
Maybe you don't need to make this so "dynamic".
Have you checked the Abstract Factory pattern? It seems that basically what you need is to create a concrete implementation for each of your interfaces based on a device type.
You don't need to have a single class implementing lots of interfaces, it is enough to have appropriate implementation of the specific interface when your code requests it.
Each concrete implementation of your abstract factory can generate several interface implementations based on your device type.
Example:
public interface IDeviceFactory
{
ISomething GetSomeInterface();
ISomethingElse GetSomeOtherInterface();
}
and then you implement the specific factory for each device:
public class SimpleDeviceFactory : IDeviceFactory
{
public virtual ISomething GetSomeInterface()
{ return Something.Empty; }
public virtual ISomethingElse GetSomeOtherInterface()
{ return new SomeSimpleConreteImplementation(); }
}
or maybe:
public class ComplexDeviceFactory : IDeviceFactory
{
public virtual ISomething GetSomeInterface()
{ return new ComplexStuff(); }
public virtual ISomethingElse GetSomeOtherInterface()
{ return new EvenMoreComplexStuff(); }
}
And then, finally, you create the right factory for your device:
public class DeviceFactory
{
public static IDeviceFactory CreateForDevice(IDevice device)
{
DeviceType type = device.Type; // or something like this
switch (type)
{
case DeviceType.Simple:
return new SimpleDeviceFactory();
case DeviceType.Complex:
return new ComplexDeviceFactory();
default:
throw new NotImplementedException();
}
}
}
Note that I have also marked IDeviceFactory method implementations as virtual, so that you can easily reuse or override specific interfaces for a specific device.
It is possible, just not easy. You need to make a string which is basically a source file and then create and use a CSharpCodeProvider, which you then order to compile your code. If it works, you can manually access your created objects through reflection.
For the interested, i did it a while back, the details are a bit foggy.
.NET 4 might make it easier, you could use one of the already mentioned framework or go the System.Reflection route. You'll find plenty of samples on the internet.
I've done both in the past. Rolling my own il.Emit stuff and using a framework (Spring.NET in my case). For anything but the trivial stuff, use one of the frameworks.
You can also try with the Re-mix project. One of the main features of this project is create mixins, that lets you add interfaces with implementations and state to other classes. Take a look this example:
using Remotion.Mixins;
using Remotion.TypePipe;
//...
public interface ITargetInterface
{
void DoSomething();
}
// . . .
public class TargetImplementation : ITargetInterface
{
public void DoSomething()
{
Console.WriteLine("ITargetInterface.DoSomething()");
}
}
// . . .
public interface IMixinInterfaceA
{
void MethodA();
}
// . . .
public class MixinImplementationA : IMixinInterfaceA
{
public void MethodA()
{
Console.WriteLine("IMixinInterfaceA.MethodA()");
}
}
// . . .
public interface IMixinInterfaceB
{
void MethodB(int parameter);
}
// . . .
public class MixinImplementationB : IMixinInterfaceB
{
public void MethodB(int parameter)
{
Console.WriteLine("IMixinInterfaceB.MethodB({0})", parameter);
}
}
Then you can merge those types to create a mixin:
var config = MixinConfiguration.BuildFromActive()
.ForClass<TargetImplementation>()
.AddMixin<MixinImplementationA>()
.AddMixin<MixinImplementationB>()
.BuildConfiguration();
MixinConfiguration.SetActiveConfiguration(config);
Unfortunately, you cannot simply call new on the TargetImplementation and expect a mixin. Instead, you have to ask Re-mix to create a TargetImplementation instance so that it can build a new type to your specification and instantiate it. When it is asked for an instance of TargetImplementation, it will return a mixin containing all of the interfaces and classes combined.
ITargetInterface target = ObjectFactory.Create<TargetImplementation>(ParamList.Empty);
target.DoSomething();
var targetAsMixinA = target as IMixinInterfaceA;
if (targetAsMixinA != null)
{
targetAsMixinA.MethodA();
}
var targetAsMixinB = target as IMixinInterfaceB;
if (targetAsMixinB != null)
{
targetAsMixinB.MethodB(30);
}

Categories

Resources