I have following situation:
IMachineService with method CreateMachine()
and I have service for every kind of machine like
MachineServiceTypeA createMachine()
and so on...
and the same from other side I have interface for all types of machines like
IMachine with method Start() and Stop()
I am thinking this way - I have to add Factory to class with Services and Factory to class Machines to be able to inject them properly with dependency injection.
I will have something like this -
services.AddTransient<IMachine, MachineA>();
services.AddTransient<IMachine, Machineb>();
services.AddTransient<IMachineFactory, MachineFactory>();
services.AddScoped<IMachineService, MachineAService>();
services.AddScoped<IMachineService, MachineBService>();
services.AddTransient<IMachineServiceFactory, MachineServiceFactory>();
This is my initial idea, but I don't thing it is good. Could you suggest me some options please, I want to be able to create for example 5 machines of type A and 3 machines of type B all of them in same collection and to keep code simple.
I believe if you use the following example of creation instances, then you will always get the last implementation of an interface:
services.AddTransient<IMachine, MachineA>();
services.AddTransient<IMachine, Machineb>();
services.AddTransient<IMachineFactory, MachineFactory>();
services.AddScoped<IMachineService, MachineAService>();
services.AddScoped<IMachineService, MachineBService>();
services.AddTransient<IMachineServiceFactory, MachineServiceFactory>();
So I believe we can create a factory and just try to get instance based on a desired type. Let me show an example.
This is the abstraction of machines:
public interface IMachine { }
And they are concrete implementations:
public class MachineA : IMachine
{ }
public class MachineB : IMachine
{ }
Then this is how abstraction of factory would look:
public interface IMachineFactory
{
IMachine GetInstanceByType(MachineType machineType);
}
And its concrete implementation:
public class MachineFactory : IMachineFactory
{
private Dictionary<MachineType, IMachine> _machineByType;
public MachineFactory(MachineA machineA, MachineB machineB)
{
_machineByType = new()
{
{ MachineType.A, machineA },
{ MachineType.B, machineB },
};
}
public IMachine GetInstanceByType(MachineType machineType) =>
_machineByType[machineType];
}
And these are type of machines:
public enum MachineType
{
A, B
}
Then instantiation of dependencies would look like this:
services.AddTransient<MachineA>();
services.AddTransient<MachineB>();
services.AddTransient<IMachineFactory, MachineFactory >();
and it is possible to use the above code like this:
private readonly IMachineFactory _machineFactory;
public FooController(IMachineFactory machineFactory)
{
_machineFactory = machineFactory;
}
[HttpGet(Name = "GetWeatherForecast")]
public IEnumerable<WeatherForecast> Get()
{
IMachine foo = _machineFactory.GetInstanceByType(MachineType.A);
// ... other code is omitted for the brevity
}