I have a Blazor server-side app where I use DynamicComponent on a page to create and add components at runtime. To do this I have the following:
A set of interfaces:
public interface IGetData
{
Task GetDataAsync(string condition);
}
public interface IGetDataA : IGetData
{
Task GetDataAsync(CriteriaA criteria);
}
public interface IGetDataB : IGetData
{
Task GetDataAsync(CriteriaB criteria);
}
And then in the page (after creating the components):
public async Task RefreshAsync()
{
var itemsA = items.Where(x => x.Ref.Instance is IGetDataA)
.Select(x => x.Ref.Instance)
.Cast<IGetDataA>();
await Parallel.ForEachAsync(itemsA, async (item, token) =>
{
await item.GetDataAsync(criteriaA);
});
var itemsB = items.Where(x => x.Ref.Instance is IGetDataB)
.Select(x => x.Ref.Instance)
.Cast<IGetDataB>();
await Parallel.ForEachAsync(itemsB, async (item, token) =>
{
await item.GetDataAsync(criteriaB);
});
}
Is it possible to unify the above into just one cast and one loop?
UPDATE
I've made changes to improve the code. I've simplified the interfaces as follows:
public interface IGetData<T>
{
Task GetDataAsync(string condition);
Task GetDataAsync(T data);
}
And the code:
bool IsGetData(object o) => o.GetType().GetInterfaces().Any(x =>
x.IsGenericType &&
x.GetGenericTypeDefinition() == typeof(IGetData<>));
var list = items.Where(x => IsGetData(x.Ref.Instance))
.Select(x => x.Ref.Instance);
await Parallel.ForEachAsync(list, async (item, token) =>
{
if (item is ItemA)
await (item as ItemA).GetDataAsync(criteriaA);
else if (item is ItemB)
await (item as ItemB).GetDataAsync(criteriaB);
});
Now I have an extra helper method and also i need to use is and as. Is there a way to simplify the code further?
item.GetDataAsync(criteriaA)actions, then you run all theitem.GetDataAsync(criteriaB)actions. Is this necessary, or could you interleave them? 2)IGetDataAandIGetDataBare both interfaces so theoretically a concrete type could implement both. Your current code will run bothGetDataAsync(CriteriaA)andGetDataAsync(criteriaB). Do you need to retain that functionality?