public class Factor1(int FactorX, int FactorY) : IFactors;
public class Factor2(int FactorX, int FactorY, int FZ) : IFactors;
public interface IFactors
{
int FactorX { get; set; }
int FactorY { get; set; }
}
public class BusinessLayerClass1
{
IFactors _factorObj;
public BusinessLayerClass1(IFactors factorObj)
{
_factorObj = factorObj;
}
public void Call() =>
new BusinessLayerClass2(_factorObj).ShowFactors();
}
public class BusinessLayerClass2
{
IFactors _factorObj;
public BusinessLayerClass2(IFactors factorObj)
{
_factorObj = factorObj;
}
public void ShowFactors()
{
Debug.WriteLine(String.Concat(_factorObj.FactorX.ToString(), " - " +
_factorObj.FactorY.ToString()));
}
}
Main program
using SimpleInjector;
class Program
{
public static void Main(string[] args)
{
List<Task> tasks = new List<Task>();
for (var i = 0; i < 10; i++)
{
tasks.Add(Task.Factory.StartNew((num) =>
{
int num_ = (int)num;
var factorObj = new Factor1() { FactorX = num_, FactorY = num_ + 1 };
var container = new Container();
var lifestyle = Lifestyle.Transient;
container.Register<BusinessLayerClass1>(lifestyle);
container.Register<BusinessLayerClass2>(lifestyle);
container.RegisterInstance<IFactors>(factorObj);
container.Verify();
var BL = container.GetInstance<BusinessLayerClass1>();
BL.Call();
}, i));
}
Task.WaitAll(tasks.ToArray());
}
}
- Here, i implement Dependency injection to BusinessLayer classes to process factors(show values in that example).
- Factor1 objects must be created at the beginning asynchronously using Task factory.
- This works but i wonder if this is the right way to implement DI(for this example)?
- If yes then, is there a better/convenient way to do that.
- If no then, how should i implement DI regarding to this example?
Factorclasses consist of runtime data and you are injecting runtime data into your application components. This practice is discourages, as I explained here. The refernced article also explains what yo do instead, which is to "let runtime data flow through the method calls of constructed object graphs.".BL.Callmethod to include that runtime data as input parameter, and later on callBL.Call(factorObj)orIFactorContextinterface/class pair, register it asScoped, and supply the runtime values to a resolvedIFactorContext.Concerning the second option, this might look like this: