List of various slightly different generic objects - c#

I am merging some code bases into one and am trying to figure out a clever way to merge some slightly different generic objects into a list that builds some of the UI for filtering.
I have many Manager objects that produce and manage ResultSets that are built on top of some of the application base classes.
Any ideas would be great. I am trying not to refactor old deep code as much as possible.
CityManager is something like
ImAFilterSetManager<ImAFilterSetBase<CityBase>>
and ChainManger is something like
ImAFilterSetManager<ImAFilterSetBase<ChainBase>>
The Manager executes the Initialize and returns a ImAFilterSetBase and wires the handler.
Is there a way to cast to something like below?
ImAFilterSetManager<ImAFilterSetBase<object>>
Execution code
List<object> filters = new List<object>() {
new CityManager(),
new ChainManager(), }
//(XXXX as object fails)
foreach (ImAFilterSetManager<ImAFilterSetBase<XXXX>> filter in filters)
{
var newFilter = filter.Initialize(_Client);
filter.OnResultsChanged += filterResults_Handler;
}
It does seem if use dyanmic i can Initialize (or at least it compliles and runs, havent tried much else) but I'm a little worried that would be bad form or cause side effects.
foreach (dynamic filter in filters)
{
var newFilter = filter.Initialize(_Client);
}
Interfaces for reference ( generic I is a ImAFilterSetBase(CityBase) and generic C would be CityBase or ChainBase class )
public interface ImAFilterSetManager<I>
{
event EventHandler<ResultSetArgs> OnResultsChanged;
I Initialize(IClient client);
}
public interface ImAFilterSetBase<C>
{
string FilterName { get; set; }
List<C> Filter { get; set; }
}

In C#, Generic<A> and Generic<B> are not related, unless you make them related. Create another non-generic class (or interface) - FilterSetManager, and have all your ImAFilterSetManager<T> derive from that, or implement that.
Then you can have a List<FilterSetManager>.

You may think in the Liskov Substitution Principle (SOLID), so a good way is relate the objects via an interface:
//defines the contract
public interface IObjectBase {
//add signatures
}
class CityBase : IObjectBase /*, IAnotherBaseA */ {
//implementation
}
class ChainBase : IObjectBase /*, IAnotherBaseB */ {
//implementation
}
Now we are going to create a constraint for the ImAFilterSetBase and rename it to AFilterSetBase
public abstract class AFilterSetBase<T> where T : IObjectBase /*, new() */ {
public string FilterName { get; set; }
public IList<T> Filters { get; set; }
}
I am going to redefine the interface ImAFilterSetManager and rename it to IFilterSetManager
public interface IFilterSetManager {
event EventHandler<ResultSetArgs> OnResultsChanged;
AFilterSetBase<IObjectBase> Initialize(IClient client);
}
Now we can create the classes that implements IFilterSetManager:
public class CityManager : IFilterSetManager {
public AFilterSetBase<IObjectBase> Initialize(IClient client) {
//TODO: implementation
throw new NotImplementedException();
}
}
//other classes that implements IFilterSetManager
class ChainManager : IFilterSetManager {
public AFilterSetBase<IObjectBase> Initialize(IClient client) {
throw new NotImplementedException();
}
}
Finally, in the end-class we can create the list as follow:
static void Main() {
IClient _client;
//_client = new ...
var filters = new List<IFilterSetManager>() {
new CityManager(),
new ChainManager()
};
foreach (var item in filters) {
var newFilter = item.Initialize(_client);
}
}
IMPLEMENTATION
An example implementation for CityManager could be as follow:
class CityFilter : AFilterSetBase<IObjectBase> {
public CityFilter(string filterName) {
this.FilterName = filterName;
this.Filters = new List<IObjectBase>();
}
}
public class CityManager : IFilterSetManager {
public AFilterSetBase<IObjectBase> Initialize(IClient client) {
var item = new CityFilter("City Filters");
item.Filters.Add(new CityBase());
return item;
}
}
And then we can test it:
static void Main(string[] args) {
IClient _client;
_client = null;
var filters = new List<IFilterSetManager>() {
new CityManager(),
new ChainManager()
};
foreach (var item in filters) {
var newFilter = item.Initialize(_client);
System.Console.WriteLine("Filter name: " + newFilter.FilterName);
System.Console.WriteLine("Filters added: " + newFilter.Filters.Count);
}
System.Console.ReadLine();
}

Related

Class with generic parameter of the same generic class type

I had a class which represents a prefix search tree:
public class PrefixTree<TData>
{
private PrefixTree<TData>[] _children;
private void SomeMethod()
{
_children = new PrefixTree<TData>[10];
}
}
Then I created a derived class with additional features for its nodes:
public class NewPrefixTree<TData> : PrefixTree<TData>
The problem is that in SomeMethod() of derived class we still create instances of base class and it doesn't fit the meaning.
I refactored the base class to this:
public abstract class PrefixTree<TData, TNode>
where TNode : PrefixTree<TData, TNode>, new()
{
private TNode[] _children;
private void SomeMethod()
{
_children = new TNode[10];
}
}
Despite the base class has complete functionality itself, I had to make it abstract because I can't write new DigitalPrefixTree<TData, DigitalPrefixTree<int, ...>>() .
But now I can use it this way and it works perfectly:
public class NewPrefixTree<TData> : PrefixTree<TData, NewPrefixTree<TData>> {} // for derived class
//or
public class PrefixTree<TData> : PrefixTree<TData, PrefixTree<TData>> {} // to use the base functionality
I've never done this before and I wonder if it's a good idea to declare a class with generic parameter of the same generic class type. Or I need to make some tricks with co/contra-variance of generic interfaces (but it probably doesn't work as I use the class type as method’s parameters type and as return type as well)?
Try this:
public interface INode<out TData>
{
TData Data { get; }
IEnumerable<INode<TData>> Children { get; }
public IEnumerable<TRequiredData> GetNestedData<TRequiredData>();
}
public interface ITree<out TData>
{
IEnumerable<INode<TData>> Children { get; }
IEnumerable<TRequiredData> GetNestedData<TRequiredData>();
}
public class Node<TData> : INode<TData>
{
public TData Data { get; }
public IEnumerable<INode<TData>> Children { get; }
public Node(TData data, IEnumerable<INode<TData>>? children = null)
{
Data = data;
Children = children ?? Enumerable.Empty<INode<TData>>();
}
public IEnumerable<TRequiredData> GetNestedData<TRequiredData>()
{
List<TRequiredData> result = new();
if (Data is TRequiredData requiredData)
result.Add(requiredData);
foreach (var child in Children)
result.AddRange(child.GetNestedData<TRequiredData>());
return result;
}
}
public class Tree<TData> : ITree<TData>
{
public IEnumerable<INode<TData>> Children { get; }
public Tree(IEnumerable<INode<TData>> children)
{
Children = children;
}
public IEnumerable<TRequiredData> GetNestedData<TRequiredData>()
{
List<TRequiredData> result = new();
foreach (var node in Children)
result.AddRange(node.GetNestedData<TRequiredData>());
return result;
}
}
And here is example of usage:
record SomeRecord();
class SomeClass {}
static void Main(string[] args)
{
var nodeWithNested = new Node<SomeClass>(
data: new SomeClass(),
children: new List<INode<SomeClass>>()
{
new Node<SomeClass>(new SomeClass()),
new Node<SomeClass>(new SomeClass())
});
var nodes = new List<INode<object>>()
{
new Node<SomeClass>(new SomeClass()),
nodeWithNested,
new Node<SomeRecord>(new SomeRecord()),
};
var tree = new Tree<object>(nodes);
var someClasses = tree.GetNestedData<SomeClass>(); // 4 items
var someRecords = tree.GetNestedData<SomeRecord>(); // 1 item
}
This approach based on out generic modifier.
The only restriction is that you can not use structs (int, bool and ect.) as they don't have common object to cast to.
Hope this will be useful.

What design pattern can be followed while implementing API that calls multiple APIs

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();

Call one method with parent class instead of two with childs

I have classes:
public class Throw
{
public double speed { get; set; }
public double accurency { get; set; }
}
public class FastThrow : Throw{}
public class LowThrow : Throw{}
Instead of having:
public static FastThrow SetFastThrow(List<object> args)
{
return new FastThrow
{
speed = (double)args[0],
accurency = (double)args[1]
};
}
public static LowThrow SetLowThrow(List<object> args)
{
return new LowThrow
{
speed = (double)args[0],
accurency = (double)args[1]
};
}
I want to have one with parent class:
public static Throw SetThrow(List<object> args)
{
return new Throw
{
speed = (double)args[0],
accurency = (double)args[1]
};
}
To declare list or some other generic interface with child class with instance of parent class. Then adding new elements to existing collection. I know that below example has compilation errors, but it should look like:
List<List<object>> firstList = new List<List<object>>();
public void Main()
{
IList<FastThrow> secondList = new List<Throw>();
foreach (var item in firstList)
{
secondList.Add(SetThrow(item));
}
}
I read about contravariance and do not know if this is possible.
You can't. Rahter than
To declare list or some other generic interface with child class with
instance of parent class.
you should
To declare list or some other generic interface with parent class with
instance of chidlren class.
The second way, as Anirban said, use generic classes, refactor your SetThrow method as following:
public static T SetThrow<T>(List<object> args) where T : Throw, new()
{
return new T
{
speed = (double)args[0],
accurency = (double)args[1]
};
}
So that you can use SetThrow method only to generate different kinds of classes as long as they are child classes. e.g:
IList<FastThrow> secondList = new List<FastThrow>();
foreach (var item in firstList)
{
secondList.Add(SetThrow<FastThrow>(item));
}
And generic classes are strong typed and elegant to use.

C# Loop Through Subclasses

Very new to C# so forgive me if this is a silly question.
If I have a base class called Validator, and a number of classes which inherit from this class such as validateFirstname, validateSecondname etc... is it possible to write a method which will loop through each of these subclasses and instantiate each?
Something along the lines of
public class loadValidators
{
public loadValidators()
{
foreach (subclass in class)
{
// instantiate class here
}
}
}
Any help is much appreciated as always.
Try this:
var validator_type = typeof (Validator);
var sub_validator_types =
validator_type
.Assembly
.DefinedTypes
.Where(x => validator_type.IsAssignableFrom(x) && x != validator_type)
.ToList();
foreach (var sub_validator_type in sub_validator_types)
{
Validator sub_validator = (Validator)Activator.CreateInstance(sub_validator_type);
}
This code assumes that all the sub classes live in the same assembly/project as the Validator class.
Also, it assumes that each of the subclasses have a public parameterless constructor.
Please note that I would not recommend this approach.
Instead you should do something like this to solve your problem (of modeling/using multiple validators):
public interface IValidator
{
bool Validate(SomeObject something);
}
public class FirstNameValidator : IValidator
{
public bool Validate(SomeObject something)
{
...
}
}
public class LastNameValidator : IValidator
{
public bool Validate(SomeObject something)
{
...
}
}
public class CompositeValidator : IValidator
{
private readonly IValidator[] m_Validators;
public CompositeValidator(params IValidator[] validators)
{
m_Validators = validators;
}
public bool Validate(SomeObject something)
{
foreach (IValidator validator in m_Validators)
{
if (!validator.Validate(something))
return false;
}
return true;
}
}
The CompositeValidator wraps multiple validators and knows how to validate objects using those validators.
You can use it like this:
var composite_validator = new CompositeValidator(new FirstNameValidator() , new LastNameValidator());
composite_validator.Validate(obj);

How to access anonymous method from generic list?

I've been working on a library to generate fake data using Faker.NET. The problem I'm having is that I don't know how to access an anonymous method that I'm passing to the constructor of my DataGenerator child classes.
The issue is that in order to create a list of generics I had to create base class DataGenerator but I cannot pull my Func<T> member up because that base class is not generic so no Tavailable. However, my DataGenerator<T> class does expose the Generator property which is my anonymous method but I haven't found a way to access it while iterating my list of data generators.
Any advice will be highly appreciated.
This is what I have so far:
public class Employee
{
public string FirstName { get; set; }
public string LastName { get; set; }
public Guid EmpUid { get; set; }
}
// Define other methods and classes here
public abstract class DataGenerator
{
public abstract int GetWeight(string matchingProperty);
public abstract Type Type { get;}
}
public abstract class DataGenerator<T> : DataGenerator
{
public readonly string[] Tags;
public readonly Func<T> Generator;
protected DataGenerator(Func<T> generator, params string[] tags)
{
Tags = tags;
//How to access this?
Generator = generator;
}
public override int GetWeight(string matchingProperty)
{
int sum = (from tag in Tags
where matchingProperty.ToLowerInvariant().Contains(tag.ToLowerInvariant())
select 1).Sum();
return sum;
}
public override Type Type {
get { return typeof(T); }
}
}
public class StringDataGenerator : DataGenerator<string>
{
public StringDataGenerator(Func<string> generator, params string[] tags) : base(generator, tags)
{
}
}
public class GuidDataGenerator : DataGenerator<Guid>
{
public GuidDataGenerator(Func<Guid> generator, params string[] tags)
: base(generator, tags)
{
}
}
And I'm testing it here:
private static void Main(string[] args)
{
var dataGeneratorList = new List<DataGenerator>
{
new StringDataGenerator(Name.First, "first", "name"),
new StringDataGenerator(Name.Last, "last", "name"),
new GuidDataGenerator(Guid.NewGuid, "uid", "id")
};
var writeProperties = typeof (Employee).GetProperties().Where(p => p.CanWrite);
foreach (var property in writeProperties)
{
foreach (var dataGenerator in dataGeneratorList)
{
if (property.PropertyType == dataGenerator.Type)
{
var weigth = dataGenerator.GetWeight(property.Name);
//How to access generator here???
var testValue = dataGenerator.Generator.Invoke();
}
}
}
}
As you tagged, given your current setup, reflection is probably your only option.
var func = dataGenerator.GetType().GetField("Generator").GetValue(dataGenerator);
var testValue = func.GetType().GetMethod("Invoke").Invoke(func, null);
I'm not sure anyone could call this super nice, and it won't be super fast, but it's probably sufficient for anything you need fake data in, I suppose.
For good measure, here's it in action.
Your question is actually a bit more complicated than it may seem at face-value. A nice way of handling this if you only ever use it in object form is just to add an abstract Generate method to the base, non-generic class:
public abstract object Generate();
Then override it in your generic one:
public override object Generate()
{
return this.Generator();
}
Of course, this return an object, which isn't nice in a generic class. But at least it avoids reflection.
Another solution to avoid this reflection nonsense might be the use of covariance, although that will, unfortunately, break for value types, like Guid.
public interface IDataGenerator<out T>
{
int GetWeight(string matchingProperty);
Type Type { get;}
T Generate();
}
public abstract class DataGenerator<T> : IDataGenerator<T>
{
public readonly string[] Tags;
public readonly Func<T> Generator;
protected DataGenerator(Func<T> generator, params string[] tags)
{
Tags = tags;
//How to access this?
Generator = generator;
}
public T Generate(){
return this.Generator();
}
. . .
}
That then turns into a preferable,
private static void Main(string[] args)
{
var dataGeneratorList = new List<IDataGenerator<object>>
{
new StringDataGenerator(Name.First, "first", "name"),
new StringDataGenerator(Name.Last, "last", "name")
// But this line doesn't work
// new GuidDataGenerator(Guid.NewGuid, "uid", "id")
};
var writeProperties = typeof (Employee).GetProperties().Where(p => p.CanWrite);
foreach (var property in writeProperties)
{
foreach (var dataGenerator in dataGeneratorList)
{
if (property.PropertyType == dataGenerator.Type)
{
var weigth = dataGenerator.GetWeight(property.Name);
var testValue = dataGenerator.Generate();
}
}
}
}

Categories