I have the following situation.
My Factory class needs to create appropriate Strategy objects based on the input string argument to the CreateStrategy function.
Strategy1, Strategy2 etc are all derived from a common StrategyBase class. However each strategy has a different Validation mechanism which is the type parameter to the Factory class. However, the StrategyValidators are not of any common type and have different interfaces.
Therefore, in the below code, I am unable to specify any common constraint on the StrategyValidator type.
I am new to C# and hence not sure if there exists any mechanism to get over this design issue. Please suggest
public class Factory
{
//Create the appropriate Concrete Implementation class based on the type
public static StrategyBase CreateStrategy<StrategyValidator>(String Type)
{
StrategyBase EnumImp = null;
// WMI based implementation
if (Type == "Type1")
{
s = Strategy1<StrategyValidator>.Instance;
}
else if (Type = "Type2")
{
s = Strategy2<StrategyValidator>.Instance;
}
return s;
}
private StrategyBase s;
}
Here's the intended usage
Factory f = new Factory();
f.CreateStrategy<WMIValidator>("WMI");
f.CreateStrategy<ABCDValidator>("ABCD");
where WMIValidator
and ABCDValidator
are unrelated types, but the actual classes created by CreateStrategy
function are related in a hierarchy e.g. having a common base StrategyBase
Here is a sample code to illustrate the issue
namespace TestCSharp
{
public interface IStrategy
{
};
public interface S1 : IStrategy
{
void f1();
void f2();
};
public class S1Concrete : S1
{
public void f1() { }
public void f2() { }
}
public interface S2 : IStrategy
{
void f3();
void f4();
};
public class S2Concrete : S2
{
public void f3() { }
public void f4() { }
};
public interface ProductBase
{
};
class Product1<T> : ProductBase where T : S1
{
};
class Product2<T> : ProductBase where T : S2
{
};
public class Factory
{
public ProductBase Create<T>(String Type)
{
if (Type == "P1")
return new Product1<T>();
else if (Type == "P2")
return new Product2<T>();
}
};
class Program
{
static void Main(string[] args)
{
Factory f = new Factory();
ProductBase s = f.Create<S1Concrete>("Type1");
}
}
}
The error I get is
The type 'T' cannot be used as type parameter 'T' in the generic type or method 'TestCSharp.Product1'. There is no boxing conversion or type parameter conversion from 'T' to 'TestCSharp.S1'.