Get Concrete Implementation of Interface with Generic Parameter - c#

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();
//...
}

Related

chain of responsibility and generics

I have a chain of responsibility that applies filters to a collection. I am trying to make a factory to build that chain of responsibility from a configuration. My concrete types for the chain arent generic but their abstraction are, and the genericity makes me struggle to put them in a collection for a mapping between config and correct chain node implementation.
Here is the implementation of the chain :
public interface IFilter<T> where T : IFilterable
{
IFilter<T> SetNext(IFilter<T> next);
IEnumerable<T> Filter(IEnumerable<T> data);
}
public class BaseFilter<T> : IFilter<T> where T : IFilterable
{
protected IFilter<T> Next { get; set; }
public IFilter<T> SetNext(IFilter<T> next)
{
Next = next;
return Next;
}
public virtual IEnumerable<T> Filter(IEnumerable<T> data)
{
return Next == null ? data : Next.Filter(data);
}
}
Here is an example of concrete implementation of the nodes of the chain :
public interface IFilterable {}
public interface ICanFly: IFilterable
{
bool CanFly { get; }
}
public interface ITransport : IFilterable
{
int Passengers { get; }
}
public class Duck : ICanFly
{
public bool CanFly => true;
}
public class Plane : ICanFly, ITransport
{
public bool CanFly => true;
public int Passengers => 5;
}
public class FlyerFilter : BaseFilter<ICanFly>
{
public override IEnumerable<ICanFly> Filter(IEnumerable<ICanFly> data)
{
return base.Filter(data.Where(x => x.CanFly));
}
}
public class SmallTransportFilter : BaseFilter<ITransport>
{
public override IEnumerable<ITransport> Filter(IEnumerable<ITransport> data)
{
return base.Filter(data.Where(x => x.Passengers < 8));
}
}
My problems start when I want to make a factory that map the configuration to my concrete types (FlyerFilter and SmallTransportFilter in my example)
public interface IFilterChainBuilder<T> where T : IFilterable
{
IFilter<T> GenerateFilterResponsabilityChain(IEnumerable<string> filtersParam);
}
public class FilterChainBuilder<T> : IFilterChainBuilder<T> where T : IFilterable
{
private readonly Dictionary<string, IFilter<T>> _paramToFiltersMap;
public FilterChainBuilder()
{
_paramToFiltersMap = new Dictionary<string, IFilter<T>>(StringComparer.OrdinalIgnoreCase)
{
{"Flyers", new FlyerFilter()}, // Compile error, cannot convert from FlyerFilter to IFilter<T>
{"SmallTransport", new SmallTransportFilter()} // Compile error, cannot convert from SmallTransportFilter to IFilter<T>
};
}
public IFilter<T> GenerateFilterResponsabilityChain(IEnumerable<string> filtersParam)
{
IFilter<T> filterResponsabilityChain = null;
foreach (var parameter in filtersParam)
if (_paramToFiltersMap.TryGetValue(parameter, out var filter))
{
if (filterResponsabilityChain == null)
filterResponsabilityChain = filter;
else
filterResponsabilityChain.SetNext(filter);
}
else
{
throw new ArgumentException(
$"config parameter {parameter} has no associated IFilter");
}
return filterResponsabilityChain ?? new BaseFilter<T>();
}
}
I can understand why it doesnt compile. Since FlyerFilter is a BaseFilter<ICanFly> (so a IFilter<ICanFly>), it would be bad if I declared a new FilterChainBuilder<PlaceholderType>. And actually since SmallTransportFilter inherit from a different T type, the only possible IFilterable implementation would have to implement both ITransport and ICanFly.
I tried to remove the generic T type entirely but the consummer of this chain of responsability relies on that IEnumerable<T> Filter(IEnumerable<T> data) signature and wants an enumeration of concrete types rather than IFilterable.
I am not sure how could I fix this problem, I am currently stuck here.
Pavel is correct - Your definition of IFilter makes the type parameter T invariant. Putting covariance/controvariance/invariance aside, the design itself is questionable. For example, FlyFilter works only against ICanFly instances, but there is no code filters the input down to ICanFly elements only - shouldn't that be the responsibility of FlyFilter as well? I would personally suggest you use type info in your filters directly, maybe something like below:
public interface IFilterable { }
public class CanFly : IFilterable { }
public class Duck : CanFly { }
public abstract class Transportation : CanFly
{
public abstract int Passengers { get; }
}
public class Plane : Transportation
{
public override int Passengers => 5;
}
public class FlyerFilter : BaseFilter<IFilterable>
{
public override IEnumerable<IFilterable> Filter(IEnumerable<IFilterable> data)
{
return base.Filter(data.Where(x => x is CanFly));
}
}
public class SmallTransportFilter : BaseFilter<IFilterable>
{
public override IEnumerable<IFilterable> Filter(IEnumerable<IFilterable> data)
{
return base.Filter(data.Where(x => x is Transportation t && t.Passengers < 8));
}
}

Implementing overload methods for subtypes of an abstract class in C#

I'm new to C#, and I would really like to implement specific different methods for each subtype of a defined abstract class, but I am having trouble figuring out how to get the compiler to do this properly. For example:
public abstract class MasterClass { }
public class SubClass1 : MasterClass { }
public class SubClass2 : MasterClass { }
public class SeparateClass
{
public void HandleMasterClass(MasterClass item)
{
/*
stuff generic to both subclasses...
*/
SpecificMethod(item)
}
public void SpecificMethod(SubClass1 item)
{
//something specific to SubClass1
}
public void SpecificMethod(SubClass2 item)
{
//something specific to SubClass2
}
}
This returns an error in compiling because there is no SpecificMethod(MasterClass item), but what I really want is for it to choose the right method based on the subclass without having to write separate HandleMasterClass(SubClass1 item) and HandleMasterClass(SubClass2 item) methods because they are mostly the same code
my main language is Jula so I'm very used to relying on multiple dispatch and doing this kind of thing. I know its probably not idiomatic in C#, so how would I do this better?
EDIT: showing that the methods are not free but part of a separate class
here's a better concrete example
public abstract class MasterClass { public abstract int Stuff(); }
public class SubClass1 : MasterClass
{
public override int Stuff() { /*calculate and return an int*/ }
}
public class SubClass2 : MasterClass
{
public override int Stuff() { /*calculate and return an int*/ }
}
public class MasterClassDictionary
{
public Dictionary<int, SubClass1> subClass1Dict{get;} = new Dictionary<int, SubClass1>()
public Dictionary<int, SubClass2> subClass2Dict{get;} = new Dictionary<int, SubClass2>()
public void Add(MasterClass item)
{
int val = item.Stuff();
AddToDict(val, item);
}
void AddToDict(int val, SubClass1 item) { subClass1Dict[val] = item; }
void AddToDict(int val, SubClass2 item) { subClass2Dict[val] = item; }
}
I know this is a bit of a contrived example, but its similar to what I'm trying to do.
Generally, you want to put code specific to a class inside that class. So your abstract class would define the specific method signature, using the abstract keyword, and the implementation would live inside the class, using the override keyword, like this:
public abstract class MasterClass {
public abstract void SpecificMethod();
}
public class SubClass1 : MasterClass {
public override void SpecificMethod()
{
//something specific to SubClass1
// use the this keyword to access the instance
}
}
public class SubClass2 : MasterClass {
public override void SpecificMethod()
{
//something specific to SubClass2
// use the this keyword to access the instance
}
}
public class SeparateClass
{
public void HandleMasterClass(MasterClass item)
{
/*
stuff generic to both subclasses...
*/
item.SpecificMethod()
}
}
Per your comment, this is how I might implement the thing in your concrete example, though it may not meet your requirements:
public class MasterClassDictionary
{
public Dictionary<int, SubClass1> subClass1Dict{get;} = new Dictionary<int, SubClass1>()
public Dictionary<int, SubClass2> subClass2Dict{get;} = new Dictionary<int, SubClass2>()
public void Add(MasterClass item)
{
int val = item.Stuff();
if (item is SubClass1)
{
subClass1Dict[val] = item;
}
if (item is SubClass2)
{
subClass2Dict[val] = item;
}
}
}
The standard design pattern for this situation is the Visitor pattern. This is a somewhat complicated pattern, but the basic idea is that the subclasses know what type they are so we are going to call over to them via an virtual method called "Accept" and they will pass themselves back as a reference. The method they call back is called Visit and is overloaded for all the possible subclasses. Here is an implementation for your example:
public abstract class MasterClass
{
public abstract int Stuff();
// New method that all subclasses will have to implement.
// You could also have this be virtual with an implementation
// for Visit(MasterClass) to provider a default behavior.
public abstract void Accept(IVisitor visitor);
}
public class SubClass1 : MasterClass
{
public override int Stuff() => 0;
// We must override this even though its the "same" code in both subclasses
// because 'this' is a reference to a different type.
public override void Accept(IVisitor visitor) => visitor.Visit(this);
}
public class SubClass2 : MasterClass
{
public override int Stuff() => 1;
// We must override this even though its the "same" code in both subclasses
// because 'this' is a reference to a different type.
public override void Accept(IVisitor visitor) => visitor.Visit(this);
}
public interface IVisitor
{
// Need an overload for all subclasses.
void Visit(SubClass1 item);
void Visit(SubClass2 item);
}
public class MasterClassDictionary
{
public Dictionary<SubClass1, int> subClass1Dict { get; } = new Dictionary<SubClass1, int>();
public Dictionary<SubClass2, int> subClass2Dict { get; } = new Dictionary<SubClass2, int>();
public void Add(MasterClass item)
{
int val = item.Stuff();
var visitor = new Visitor(this, val);
item.Accept(visitor);
}
void AddToDict(SubClass1 item, int val) { subClass1Dict[item] = val; }
void AddToDict(SubClass2 item, int val) { subClass2Dict[item] = val; }
// Provides the visitor implementation that holds any state that might
// be needed and dispatches to the appropriate method.
private class Visitor : IVisitor
{
private MasterClassDictionary _parent;
private int _value;
public Visitor(MasterClassDictionary parent, int val)
{
_parent = parent;
_value = val;
}
public void Visit(SubClass1 item) => _parent.AddToDict(item, _value);
public void Visit(SubClass2 item) => _parent.AddToDict(item, _value);
}
}
That said, C# has added pattern matching with switch that would look substantially simpler. It's only downside is that it is doing more type checks which might be slower if this is in some really performance sensitive code, but is certainly going to be faster than using dynamic:
public void Add(MasterClass item)
{
int val = item.Stuff();
switch (item)
{
case SubClass1 i: AddToDict(i, val); break;
case SubClass2 i: AddToDict(i, val); break;
}
}

Implementing FactoryPattern without using an Interface 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>();
}
}
}

Problems with generics

I'm facing a problem with generics:
public interface IEntity {}
public class User : IEntity {}
public class Experiments {
private IList<IEntity> list;
private IList<Action<IEntity>> actions;
public Experiments(){
list = new List<IEntity>();
actions = new List<Action<IEntity>>();
}
public void Add<T>(T entity) where T : IEntity {
list.Add(entity); // -> NO PROBLEM HERE
}
public void AddAction<T>(Action<T> handle) where T : IEntity {
actions.Add(handle); // -> HERE I GET AN ERROR
}
Why I get "cannot convert from 'System.Action<T>' to 'System.Action<IEntityCheck>..." once I specified on the method's signature that T is IEntity?
I managed to get it to compile by declaring the generic type at the class level.
public interface IEntity { }
public class User : IEntity { }
public class Experiments<T> where T : IEntity
{
private IList<T> list;
private IList<Action<T>> actions;
public Experiments()
{
list = new List<T>();
actions = new List<Action<T>>();
}
public void Add(T entity)
{
list.Add(entity);
}
public void AddAction(Action<T> handle)
{
actions.Add(handle);
}
}
Try:
public void AddAction(Action<IEntity> handle)
{
actions.Add(handle);
}
And for your add function there is no need to add a type parameter, just use the interface.
public void Add(IEntity entity)
{
list.Add(entity);
}
The issue with public void AddAction<T>(T entity) where T : IEntity is I could (if it worked) pass in a function like Foo(ConcreteEntity entity) that uses member on the concrete class, that are not defined on the interface, then I wouldn't be able to loop through the list of Actions<IEntity> and calling them all with some other implementation of IEntity and have them all succeed.
Thank you all for the answers, I figured out a way to solve the issue.
I just changed the actions List<Action<T>> to List<Delegate> and now all works fine...
...
private IList<IEntity> list;
private IList<Delegate> actions;
public void AddAction<T>(Action<T> handle) where T : IEntity {
actions.Add(handle);
}
...
Thanks.

Can I combine replace these methods in derived class with a method in the base class?

I have methods like this:
public void AddOrUpdate(Product product)
{
try
{
_productRepository.AddOrUpdate(product);
}
catch (Exception ex)
{
_ex.Errors.Add("", "Error when adding product");
throw _ex;
}
}
public void AddOrUpdate(Content content)
{
try
{
_contentRepository.AddOrUpdate(content);
}
catch (Exception ex)
{
_ex.Errors.Add("", "Error when adding content");
throw _ex;
}
}
plus more methods that differ only in the class passed to them.
Is there some way that I could code these methods in a base class rather than repeating the method in each derived class? I was thinking something based on generics but I am not sure how to implement and also not sure how to pass in the _productRepository.
FYI here's the way _productRepository and _contentRepository are defined:
private void Initialize(string dataSourceID)
{
_productRepository = StorageHelper.GetTable<Product>(dataSourceID);
_contentRepository = StorageHelper.GetTable<Content>(dataSourceID);
_ex = new ServiceException();
}
yes you can.
easy way to do is to use interfaces and inheritance. tight coupled
Another way to do is Dependency injection. lose coupled, preferable.
Yet another way is to use generics as follows:
public void AddOrUpdate(T item ,V repo) where T: IItem, V:IRepository
{
repo.AddOrUpdate(item)
}
class Foo
{
IRepository _productRepository;
IRepository _contentRepository
private void Initialize(string dataSourceID)
{
_productRepository = StorageHelper.GetTable<Product>(dataSourceID);
_contentRepository = StorageHelper.GetTable<Content>(dataSourceID);
_ex = new ServiceException();
}
public void MethodForProduct(IItem item)
{
_productRepository.SaveOrUpdate(item);
}
public void MethodForContent(IItem item)
{
_contentRepository.SaveOrUpdate(item);
}
}
// this is your repository extension class.
public static class RepositoryExtension
{
public static void SaveOrUpdate(this IRepository repository, T item) where T : IItem
{
repository.SaveOrUpdate(item);
}
}
// you can also use a base class.
interface IItem
{
...
}
class Product : IItem
{
...
}
class Content : IItem
{
...
}
Try to use Generic Methods There dude and implement it on your base class
you could try this link: http://msdn.microsoft.com/en-us/library/twcad0zb(v=vs.80).aspx

Categories