Implementing FactoryPattern without using an Interface C# - c#

I have a requirement of refactoring the code where I have multiple classes and the object of the classes need to be created dynamically depending upon the user request. Now the classes are all there and have no common methods within them that match each other. So I cannot add an interface to it and create a factory class that will return the interface reference referencing the actual class. Is there a way with generics or any other way to refactor this to be able to create objects dynamically. The approach we have now is that there is a main class where the object of each class is instantiated and all methods are being called. Can we implement a factory pattern without an interface or any solution to my scenario ? Please.
Adding sample code to explain the scenario.
public interface ITest
{
string TestMethod1(string st, int ab);
int TestMethod2(string st);
void TestMethod4(int ab);
float ITest.TestMethod3(string st);
}
public class Class1 : ITest
{
public string TestMethod1(string st, int ab)
{
return string.Empty;
}
public void TestMethod4(int ab)
{
throw new NotImplementedException();
}
public int TestMethod2(string st)
{
throw new NotImplementedException();
}
public float TestMethod3(string st)
{
throw new NotImplementedException();
}
}
public class Class2 : ITest
{
float ITest.TestMethod3(string st)
{
return float.Parse("12.4");
}
void ITest.TestMethod4(int ab)
{
throw new NotImplementedException();
}
public string TestMethod1(string st, int ab)
{
throw new NotImplementedException();
}
public int TestMethod2(string st)
{
throw new NotImplementedException();
}
}
public class Main
{
ITest test = null;
public ITest CreateFactory(TestType testType)
{
switch(testType)
{
case TestType.Class1:
test = new Class1();
break;
case TestType.Class2:
test = new Class2();
break;
}
return test;
}
}
enum TestType
{
Class1,
Class2
}
So, as in above, I can't have the interface because no common methods are in it. So what other solutions I can have, if I have an empty interface or abstract method, how will that help. Even if I put one common method in the interface and all classes implement it, since I am passing the reference to the interface, I can only access the common method from the interface reference.
My idea is to use something like the below, but not sure what the return type would or should be defined as.
public T CreateFactory(TestType testType)
{
switch(testType)
{
case TestType.Class1:
return GetInstance<Class1>("Class1");
case TestType.Class2:
return GetInstance<Class1>("Class2");
}
return null;
}
public T GetInstance<T>(string type)
{
return (T)Activator.CreateInstance(Type.GetType(type));
}
How do I define T here in the return is my concern and how can I invoke it, if anybody can help with that, then I think I am close to the solution.
Answer to my problem
public static T CreateFactory<T>()
where T: IFactory, new()
{
return new T();
}

I'm not saying totally understand the problem, but give it a shot...
Factory like class that you have:
class Factory
{
public static Visitable Create(string userInput)
{
switch (userInput)
{
case nameof(ClassA):
return new ClassA();
case nameof(ClassB):
return new ClassB();
default:
return null;
}
}
}
Types that you have to create:
class ClassA : Visitable
{
public void M1(){}
public override void Accept(Visitor visitor){visitor.Visit(this)}
}
class ClassB : Visitable
{
public void M2(){}
public override void Accept(Visitor visitor){visitor.Visit(this)}
}
Usage of the code:
var visitor = new Visitor();
var obj = Factory.Create("ClassA");
obj.Accept(visitor);
And the missing parts:
class Visitor
{
public void Visit(ClassA obj){ obj.M1(); } // Here you have to know what method will be called!
public void Visit(ClassB obj){ obj.M2(); } // Here you have to know what method will be called!
}
abstract class Visitable
{
public abstract void Accept(Visitor visitor);
}
This is called the Visitor pattern. If you know what methods need to be called Visitor.Visit than that is what you want.

I don't entirely understand your question but a basic assertion is wrong. I am concerned with your design given the basis of your question.
Regardless, my proposed solution:
You are saying that you don't have a common object (indirect, directly you stated: "I can't have the interface because no common methods are in it."
object is the common element.
I don't condone this but you could create a factory object that just returned object as the data type. The problem with this is you then have to cast it after the object creation which you may not mind...
internal class MyFactory
{
internal object CreateItem1() { return ...; }
internal object CreateItem2() { return ...; }
internal object CreateItem2(ExampleEnum e)
{
switch(e)
{
case e.Something:
return new blah();
default:
return new List<string>();
}
}
}

Related

when i want to have a base Interface and implement from it the call is ambiguous between the following methods or properties

I know that the call is ambiguous between the following methods or properties and
I know the meaning of this error but You see this implementation .
I saw examples of each class being created on the interface, but I use the IOC.
interface IOne
{
void Save(string text);
}
interface ITwo
{
void Save(string two);
}
class One : IOne
{
public void Save(string text)
{
throw new NotImplementedException();
}
}
class Two : ITwo
{
public void Save(string two)
{
throw new NotImplementedException();
}
}
interface IBase : IOne, ITwo
{
}
class Base : IBase
{
void ITwo.Save(string two)
{
throw new NotImplementedException();
}
void IOne.Save(string text)
{
throw new NotImplementedException();
}
}
class RunClass
{
private readonly IBase _base;
public RunClass(IBase #base)
{
this._base = #base;
}
public void SaveMethod(string t = "Test")
{
_base.Save(t);
}
}
when i call this line _base.Save(t); i get this error the call is ambiguous between the following methods or properties. Is there a way to implement this type of implementation?
At first you need to know which of the two Save methods you want to call. Then you can implement it by casting explicitly:
public void SaveMethod(string t = "Test")
{
((IOne)_base).Save(t);
// or
((ITwo)_base).Save(t);
}

C# specialize generic class

Is it possible to do the following specialization in C#? I can do this in C++ but do not understand how to achieve the same result in C#.
class GenericPrinter<T>
{
public void Print()
{
Console.WriteLine("Unspecialized method");
}
}
class GenericPrinter<int>
{
public void Print()
{
Console.WriteLine("Specialized with int");
}
}
Added:
The problem with suggested GenericPrinterInt solution is that I need to explicitly create it. new GenericPrinter<int> will still print Unspecialized method.
What I want is to use this GenericPrinter from another generic class without the knoledge is T equal to int or something else.
I guess the closer you could get in C# would be:
class GenericPrinter<T>
{
public virtual void Print()
{
Console.WriteLine("Unspecialized method");
}
}
class IntPrinter : GenericPrinter<int>
{
public override void Print()
{
Console.WriteLine("Specialized with int");
}
}
Otherwise, the answer is, you can't specialize in C#.
As Lyubomyr Shaydariv said in his comment:
C++ templates are not .NET generics. You can't.
From your edit I guess you will have some type checking to make.
You can do this with a dictionary for example.
class GenericPrinter<T>
{
private Dictionary<Type, Action> _actions
= new Dictionary<Type, Action>()
{
{ typeof(int), PrintInt }
};
public virtual void Print()
{
foreach (var pair in _actions)
if (pair.First == typeof(T))
{
pair.Second();
return ;
}
Console.WriteLine("Unspecialized method");
}
public virtual void PrintInt()
{
Console.WriteLine("Specialized with int");
}
}
Like you can see, you will have to make a method for each type, you want to handle. And you may also encounter some issues when you will try to manipulate T as int. Since, T is really generic (it hasn't any constraint), it will more likely act as an object in your code (not at runtime) you will have to cast it like that (int)(object)yourTVariable in your methods where you are sure that T is an int.
But for this part, I guess some of my peers, will have a better answer than me to give to you.
If it's just about displaying which type you are using:
public virtual void Print()
{
Console.WriteLine($"Specialized with {typeof(T).Name}");
}
But you won't have the unspecialized message anymore (and if you think about it, you can't have a GenericPrinter instantiated without specifying its type. Then it makes no sense to have a method that displays "unspecialized", you will always have a specified type)
Anyway, the answer is still the same, you can't specialize a generic in C#.
It isn't possible in C#.
You can use inheritance instead:
class GenericPrinter<T>
{
public virtual void Print()
{
Console.WriteLine("Unspecialized method");
}
}
class GenericPrinterInt : GenericPrinter<int>
{
public override void Print()
{
Console.WriteLine("Specialized with int");
}
}
According to the updated question, I can only suggest you the following approach. You could create a static factory method in which you can check the type of T and instantiate an appropriate specialized class if the type matches the criteria:
class GenericPrinter<T>
{
public static GenericPrinter<T> Create()
{
if (typeof(int).IsAssignableFrom(typeof(T)))
return (GenericPrinter<T>)(object)new GenericPrinterInt();
if (typeof(double).IsAssignableFrom(typeof(T)))
return (GenericPrinter<T>)(object)new GenericPrinterDouble();
// Other types to check ...
return new GenericPrinter<T>();
}
public virtual void Print()
{
Console.WriteLine("Unspecialized method");
}
}
class GenericPrinterInt : GenericPrinter<int>
{
public override void Print()
{
Console.WriteLine("Specialized with int");
}
}
class GenericPrinterDouble : GenericPrinter<double>
{
public override void Print()
{
Console.WriteLine("Specialized with double");
}
}
Some other generic class:
class SomeGenericClass<T>
{
public readonly GenericPrinter<T> Printer = GenericPrinter<T>.Create();
}
Usage sample:
var intClass = new SomeGenericClass<int>();
intClass.Printer.Print();
// Output: Specialized with int
var doubleClass = new SomeGenericClass<double>();
doubleClass.Printer.Print();
// Output: Specialized with double
var stringClass = new SomeGenericClass<string>();
stringClass.Printer.Print();
// Output: Unspecialized method
You can do it but you need to move your code into lambda expressions
or some flavor of lambdas.
It's not pretty but is fast ( no lookups ) and has the specialization.
You can tailor this to your needs
Cummon Microsoft we shouldn't have to do this.
How many improvements to .Net and no specialization.
public class GenericPrinter<T>
{
public static GenericPrint()
{
T thing = default(T)
switch(thing)
{
case int ival:
_Print = ()=>
{
Console.WriteLine("Specialized Int print Code");
};
break;
default:
_Print = ()=>
{
Console.WriteLine("Some generic print code");
};
break;
}
}
// will be unique for every type of T
public static Action _Print=null;
public void Print()
{
_Print();
}
}
Use would be the same
var printer = new GenericPrinter<int>();
printer.Print();

Get Concrete Implementation of Interface with Generic Parameter

I'm feeling pretty dumb right now. Not sure why I can't solve this. I have a repository interface:
public interface ICollateralItemBaseImplementation<T> where T : CollateralItemBase
{
int Add(T collateralItem);
T Get(int collateralID);
}
and many implementations, each implementing one of the 10 models that inherit from CollateralItemBase. For example:
internal sealed class CollateralItemCertifiedDepositRepository : ServiceBaseRepository, ICollateralItemBaseImplementation<CollateralItemCertifiedDeposit>
{
int Add(CollateralItemCertifiedDeposit collateralItem) { /*...*/ }
CollateralItemCertifiedDeposit Get(int collateralID) { /*...*/ }
}
Now i just need to switch on the incoming CollateralItemBase type to get the repository I need:
private ICollateralItemBaseImplementation<???> GetRepository(CollateralItemBase item)
{
switch (item.GetType().Name)
{
case "CollateralItemCertifiedDeposit": return new CollateralItemCertifiedDepositRepository();
//...
}
I just need to figure out what to return from this method, for other methods to act on whichever repository I return. How do I refactor this to get it working?
I'm pretty sure I have a covariance/contravariance problem. Again, I'm feeling pretty dumb, just drawing a blank.
Thanks.
You could do it in two stages. Add a non-generic base interface to ICollateralItemBaseImplementation then cast to the generic version.
public interface ICollateralItemBaseImplementation
{
}
public interface ICollateralItemBaseImplementation<T> : ICollateralItemBaseImplementation
where T : CollateralItemBase
{
int Add(T collateralItem);
T Get(int collateralID);
}
public static class RepositoryFactory
{
public static ICollateralItemBaseImplementation<T> GetRepository<T>(T item)
where T : CollateralItemBase
{
return (ICollateralItemBaseImplementation<T>)GetRepositoryImpl(item);
}
private static ICollateralItemBaseImplementation GetRepositoryImpl<T>(T item)
where T : CollateralItemBase
{
switch (item.GetType().Name)
{
case "CollateralItemCertifiedDeposit":
return new CollateralItemCertifiedDepositRepository();
}
return null;
}
}
internal static class Program
{
static void Main()
{
var repo = RepositoryFactory.GetRepository(new CollateralItemCertifiedDeposit());
Debug.Assert(repo is CollateralItemCertifiedDepositRepository);
}
}
what about a generic return param of base type
private ICollateralItemBaseImplementation<T> GetRepository(CollateralItemBase item) where T : ServiceBaseRepository
{
switch (item.GetType().Name)
{
case "CollateralItemCertifiedDeposit": return new CollateralItemCertifiedDepositRepository();
//...
}

How to prevent an instantiation of an object in c#

What I need is to check the parameters passed to the constructor and prevent the instantiation of the specific object in case they are treated as invalid.
What I have found is that an exception can be thrown so the object reference will end up with "null" as expected.
For example, this class will be instantiated only if the integer passed to the constructor is non negative.
class MyClass
{
public MyClass(int a)
{
if (a < 0)
{
throw new Exception();
}
}
}
Although the above works fine, I bet that c# can provide a cleaner way to do this, avoiding the extra cost of the try/catch need, each time a new object is about to be constructed.
static void Main(string[] args)
{
MyClass e1;
MyClass e2;
try
{
e1 = new MyClass(1);
}
catch(Exception) { }
try
{
e2 = new MyClass(-1);
}
catch(Exception) { }
}
In cases like this, you should consider using the Factory Pattern. You made the constructor private, and instead use a static method to return an instance.
public class Foo {
private Foo(int a) { ... }
public static Foo GetFoo(int a) {
if (a < 0) {
throw new Exception("No Foo for you!");
// or
return null;
}
return new Foo(a);
}
}
public class Program {
public static void Main() {
Foo f;
f = new Foo(); // Not allowed, ctor is private.
f = Foo.GetFoo(42); // Do this instead.
}
}
With this, you can do some pretty interesting stuff.
Here, we have a Foo class, with different sub-classes. By using the Factory Pattern, we can construct an instance of a particular Foo sub-class, without the outside world even knowing that any subclasses exist!
public abstract class Foo {
// Private implementations of Foo
// No one outside can ever construct one directly.
private class RedFoo : Foo { }
private class GreenFoo : Foo { }
private class BlueFoo : Foo { }
public static Foo GetColoredFoo(string color) {
switch (color.ToLower()) {
case "red": return new RedFoo();
case "green": return new GreenFoo();
case "blue": return new BlueFoo();
}
throw new Exception("No Foo for that color!");
}
}
public class Program {
public static void Main() {
Foo f;
f = new Foo(); // Not allowed; Foo is abstract
f = new RedFoo(); // Not allowed, RedFoo is private, inside of Foo
f = Foo.GetColoredFoo("red"); // Returns an instance of RedFoo
}
}
This moves the knowledge of "how to best construct the object you really need" into the definition of the class itself, and of course eliminates the try/catch. You could apply any logic you need inside of the static factory method.
You can go with the factory pattern, as suggested by MarcinJruaszek, by making the constructor private and add a static method:
public class myClass
{
private myClass(int a)
{
// constructor
}
public static myClass Create(int a){
if (a < 0)
{
return null;
}
return new myClass(a);
}
}
And do myClass.Create(1).
What I suggest you do is create a static method of your class that accepts the parameters you need to verify and have that return the object. I do not know of a way to abandon object creation during a constructor without throwing an Exception.

Receiving dynamically changing classes

In my system I have 16 different classes alike used for statistics. They look like the following
public class myClass : myInheritage
{
private static myClass _instance;
public static myClass Instance
{
get { return _instance ?? (_instance = new myClass(); }
}
public static void Reset()
{
_instance = null;
}
}
They are all made into singletons
myInheritage looks like this:
public class myInheritage
{
int data = 0;
public myInheritage()
{
}
public int Data
{
get { return data; }
set { data+= value; }
}
}
The program is made, so the user chooses which class he wants to make statistics with.
Something like this is what I want
public void statistics(Object myObject, string name)
{
Object x = myObject;
x.Data = 10;
x.Data();
}
Called from another class
statistics(myClass.Instance, "myClass");
statistics(myClass2.Instance, "myClass2)";
So I want to dynamically change my instance in my statistics class.
Is that possible with .NET 2.0 ?
You could use reflection...
MethodInfo method = myObject.GetType().GetMethod("Reset");
if (method != null) method.Invoke(myObject, null);
If you can modify the classes themselves, a better approach might be to have each implement an interface (or base class) IResettable.
public interface IResettable
{
void Reset();
}
public class myClass : myInheritage, IResettable
{
public void Reset() { ... }
}
Then you could write the function against the interface:
public void statistics(IResettable myObject, string name)
{
myObject.Reset();
}
Yes. What you want here is a Strategy/Factory pattern. I name both as they could be used in conjunction for your case. There are great examples of these design patterns here and the following are detailed intros to the Strategy pattern and the Factory pattern. The former of the last two links also shows you how to combine the two to do exactly waht you require.
So in your case, you could set up the following interface
public interface IStatistics
{
// Some method used by all classes to impose statistics.
void ImposeStatistics();
}
Then in you singleton classes you could have
public class myClass : myInheritage, IStatistics
{
private static myClass _instance;
public static myClass Instance
{
get { return _instance ?? (_instance = new myClass()); }
}
public static void Reset()
{
_instance = null;
}
// You would also inherit from IStatistics in your other classes.
public void ImposeStatistics()
{
// Do stuff.
}
}
Then you would have a 'factory' class that imposes you stratgey at runtime.
public static class StatisticFactory
{
public static void ImposeStatistics(IStatistics statsType)
{
statsType.ImposeStatistics();
}
/// <summary>
/// Get the conversion type.
/// </summary>
/// <param name="col">The column to perform the conversion upon.</param>
public static IStatistics GetStatsType(string typeName)
{
switch (typeName)
{
case "BoseEinstein":
return new BoseEinsteinStats();
case "FermiDirac":
return new FermiDiracStats();
default:
return null;
}
}
}
You can then call this like
// Run stats.
IStatistics stats = StatisticFactory(GetStatsType("BoseEinstein"));
to get the statistics for the required class.
I hope this helps.

Categories