0
\$\begingroup\$

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?

asked Apr 23, 2019 at 8:22
\$\endgroup\$
4
  • \$\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\$ Commented 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\$ Commented 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\$ Commented 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\$ Commented Apr 23, 2019 at 8:28

1 Answer 1

1
\$\begingroup\$

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.

answered Apr 23, 2019 at 14:00
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.