I currently have two (core) classes :
public abstract class BO<TConfig> where TConfig : BOConfigBase
{
protected TConfig Config { get; set; }
internal List<BC> _BCs { get; set; }
public abstract void Init();
public void Process() => _BCs.ForEach(bc => bc.Process());
}
public class BOOne : BO<BOConfigOne>
{
public BOOne(BOConfigOne config)
{
Config = config;
}
public override void Init()
{
_BCs = new List<BC>()
{
BCA.Init(Config),
BCB.Init(Config),
BCC.Init(Config),
BCOneA.Init(Config)
};
}
}
Then the code for my BCs
public abstract class BC
{
protected BOConfigBase Config { get; set; }
public abstract void Process();
}
public class BCA : BC
{
private BCA()
{
}
public static BCA Init(BOConfigBase config)
{
BCA ret = new BCA { Config = config };
return ret;
}
public override void Process()
{
Config.Counter += 1;
}
}
To call this, I will do this :
static void Main()
{
{
var boConfigOne = new BOConfigOne()
{
A = "one",
B = "one",
C = "one",
One = "one"
};
var testBO = new BOOne(boConfigOne);
testBO.Init();
testBO.Process();
Console.WriteLine(
$"A = {boConfigOne.A}, B = {boConfigOne.B}, C = {boConfigOne.C}, One = {boConfigOne.One}, Counter = {boConfigOne.Counter}");
}
{
var boConfigTwo = new BOConfigTwo()
{
A = "two",
B = "two",
C = "two",
Two = "two"
};
var testBOTwo = new BOTwo(boConfigTwo);
testBOTwo.Init();
testBOTwo.Process();
Console.WriteLine(
$"A = {boConfigTwo.A}, B = {boConfigTwo.B}, C = {boConfigTwo.C}, Two = {boConfigTwo.Two}, Counter = {boConfigTwo.Counter}");
}
Console.ReadKey();
}
BO stands for Business Orchestration, and BC for Business Component. A BC would perform a single function, and a BO would contain several of these re-usable BCs.
I would like to change the BO to be able to Init all the BCs generically, something like Init => BCs.Foreach(bc => bc.Init(Config));
. The problem is that my BC's Init's are static, hence I can't put it in an interface, and call it on the interface, nor can I put it in the base abstract method, and override it.
Does anyone have a better solution for me?
-
\$\begingroup\$ We can help you (better) and review the code when you show us your real implementation. This looks very much like pseudocode or hypothetical one. \$\endgroup\$t3chb0t– t3chb0t2019年04月23日 08:23:39 +00:00Commented Apr 23, 2019 at 8:23
-
\$\begingroup\$ @t3chb0t. This is the current working set of code I have as a POC. If I can get this to work, I will then implement it completely. I'll add the basic call of the methods to show the test implementation of it as well. \$\endgroup\$WynDiesel– WynDiesel2019年04月23日 08:26:26 +00:00Commented Apr 23, 2019 at 8:26
-
1\$\begingroup\$ This is a very good idea. Could you tell us at least what BCA, BO etc stand for so we have some more context? \$\endgroup\$t3chb0t– t3chb0t2019年04月23日 08:27:32 +00:00Commented Apr 23, 2019 at 8:27
-
\$\begingroup\$ @t3chb0t, my apologies. So used to use the terms in my environment, I forgot to add. BC stands for Business Component, BO stands for Business Orchestration. So, a BO would contain several (reusable in other BO) BC's, that would perform a single function, like updating the DB, writing a file, etc. \$\endgroup\$WynDiesel– WynDiesel2019年04月23日 08:28:58 +00:00Commented Apr 23, 2019 at 8:28
1 Answer 1
To be honest it's hard to follow with such abstract class names and POC. The root of what you are describing is you have a factory method to create one of your classes. Lucky for you it seems all the factory methods have the same method signature. We can make this a bit easier.
Need to store the factory methods in a private field to be used by the Init method. Also adding a "helper" method to make storing the factories easier.
public abstract class BO<TConfig> where TConfig : BOConfigBase
{
protected TConfig Config { get; set; }
internal List<BC> _BCs { get; set; }
private Func<BOConfigBase, BC>[] _factories = new Func<BOConfigBase, BC>[0];
protected void SetFactories(params Func<BOConfigBase, BC>[] factories)
{
_factories = factories;
}
public void Init()
{
_BCs = _factories.Select(b => b(Config)).ToList();
}
public void Process() => _BCs.ForEach(bc => bc.Process());
}
Now BOOne class can call it like
public class BOOne : BO<BOConfigOne>
{
public BOOne(BOConfigOne config)
{
Config = config;
SetFactories(BCA.Init, BCB.Init, BCC.Init, BCOneA.Init);
}
}
I'm assuming each BO class would take different BC classes if not then you could constructer inject all the factories.