Yesterday, One of my friends asked me to create a program(Must implement Dependency Injection) which return speed of the car. So, I have created a small program in which I tired to implement constructor injection.
class Program
{
static void Main(string[] args)
{
Maruti objMaruti = new Maruti();
clientClass obj = new clientClass(objMaruti);
obj.getSpeed();
}
}
public class clientClass
{
ISpeed _ISpeed;
public clientClass(ISpeed obj)
{
this._ISpeed = obj;
}
public int getSpeed()
{
return _ISpeed.Speed();
}
}
public interface ISpeed
{
int Speed();
}
public class Maruti : ISpeed
{
public int Speed()
{
return 200;
}
}
public class Audi : ISpeed
{
public int Speed()
{
return 400;
}
}
public class BMW : ISpeed
{
public int Speed()
{
return 600;
}
}
Now, In main Method, my friend can check speed of any car.
class Program
{
static void Main(string[] args)
{
Maruti objMaruti = new Maruti();
clientClass obj = new clientClass(objMaruti);
obj.getSpeed();
}
}
He asked me a question that why you have created this constructor Injection and client class. If you directly call the class, you would get the result.
class Program
{
static void Main(string[] args)
{
Maruti objMaruti = new Maruti();
objMaruti.Speed();
//If user wants to check Audi Speed.
Audi objAudi = new Audi();
objAudi.Speed();
}
}
Is he right? which way is best and why ?
I think the poor naming made your friend to ask you this question. What if you had the requirement to log the speed of different cars? The client class would have this name
public class SpeedLog
{
ISpeed speed;
ILogger logger;
public SpeedLog(ISpeed speed, ILogger logger)
{
this.speed = speed;
this.logger = logger;
}
public void Information()
{
logger.Information($"{speed.GetType().Name} is running with {speed.Speed()}");
}
}
This client class can log the speed of any object as long as the object has the Speed method in its public interface. The ISpeed interface gives us the opportunity to define the signature of the Speed method. Now the SpeedLog type doesn't depend on a particular type like Maruti or Audi or even a base type Car, if any, to retrieve the speed info. SpeedLog can now log the speed of stars if the Star type implements the ISpeed interface. When we add the new Star type we will only need to compile the library which contains this type and the library of the SpeedLog type remains untouched. An Inversion of Control library can now inject the Star object if it is asked to do so.
Related
Good day. I have a problem of understanding the Dependency Injection.
So what exactly do I need is to have access from child objects to parent objects.
For example, I have my MainProgram object. This object creates another object, another object create 3-d objects and so on. Let's stop on child object #5
This child needs to have a reference to object #1.
I don't understand how to do this in a better way. But then I started to search and find something called Dependency Injection.
I really hope that this thing is the right answer for my issue (If not, please tell).
So here in my problem and example.
I'm trying to create a WEB API for one of my services. Using ASP .NET Core 6
First, I created a simple class that will be MainProgram, when Server will receive POST request with needed data, it will launch some working in multi-threading.
public class MainProgram
{
public int MaxThreads { get; set; }
public int OrderCounter { get; set; }
public AdjustableSemaphore Semaphore { get; set; }
public MainProgram(int maxThreads)
{
MaxThreads = maxThreads;
Semaphore = new AdjustableSemaphore(MaxThreads);
}
public async Task StartOperation(IApiOperation operation)
{
try
{
operation.Prepare();
operation.Start();
while (!operation.IsReady())
{
await Task.Delay(500);
}
operation.Finish();
}
catch (Exception e)
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine(e.Message);
Console.ResetColor();
}
}
public string OperationStatus(IApiOperation operation)
{
return operation.ShowDetails();
}
}
Then I added this class to Program.cs for Dependency.
builder.Services.AddSingleton(program => new MainProgram(1000));
I made a Constructor for my Controller as it was in the example I read and all worked great.
Controller create instance of MainProgram by its own.
[ApiController]
[Route("/")]
public class ApiController : ControllerBase
{
private MainProgram _mainProgram;
public ApiController(MainProgram mainProgram)
{
_mainProgram = mainProgram;
}
[HttpPost]
[Route("test")]
public string Get()
{
TestOperation to = new TestOperation(_mainProgram);
new Thread(() =>
{
var project = _mainProgram.StartOperation(to);
}).Start();
return $"Started task #{to.Id}";
}
}
The problems that I have are in this line
TestOperation to = new TestOperation(_mainProgram);
This TestOperation also has a Dependency from MainProgram. I understand that I can pass my private _mainProgram in it.
But let's pretend that TestOperation also has a child, and this child also has a child, and only the third one needs a link to MainProgram.
I thought that's where Dependency Injection helps.
Main Question is
How can I create objects that have a constructor with dependency for MainProgram,
If I cannot write new TestOperation(WITHOUT ATTRIBUTE)? It will be a syntax error.
I think you'd avoid the cycle of dependency;
If you couldn't avoid it ,you could try to inject the IServiceProvider into your services,and get the target service with provider.GetService() method,and you could try to create a Parameterservice or Static class to hold the parameter you need,
I tried as below :
Services:
interface IA {int methodA();}
interface IB { int methodB(); }
interface IC { int methodC(); }
interface IParameterService { }
public class ParameterService: IParameterService
{
public int APara;
public int BPara;
public ParameterService(int para)
{
APara = para+1;
}
}
public class A : IA
{
private readonly IServiceProvider _provider;
private readonly int Id;
public A(IServiceProvider provider)
{
_provider = provider;
Id = (provider.GetService(typeof(IParameterService)) as ParameterService).APara;
}
public int methodA()
{
return Id+1;
}
}
public class B : IB
{
private readonly IServiceProvider _provider;
public B(IServiceProvider provider)
{
_provider = provider;
}
public int methodB()
{
return (_provider.GetService(typeof(IA)) as A).methodA();
}
}
public class C : IC
{
private readonly IServiceProvider _provider;
public C(IServiceProvider provider)
{
_provider = provider;
}
public int methodC()
{
return (_provider.GetService(typeof(IB)) as B).methodB();
}
}
In startup:
services.AddTransient<IParameterService>(x => new ParameterService(1));
services.AddTransient<IA,A>();
services.AddTransient<IB,B>();
services.AddTransient<IC, C>();
in controller:
private readonly A _A;
private readonly C _C;
public SomeController(IServiceProvider provider)
{
_A = (A)provider.GetService(typeof(IA));
_C=(C)provider.GetService(typeof(IC));
}
Result:
I am new to programming and learning through online stuff and you guys, nowadays! I am reading about Factory Design Pattern and tried to implement in the very basic project, I have a solution that has two projects one projects contain interfaces, and the other contains implementation, I have read about factories but unfortunately, I have no idea how to implement in my project, In one project, I have 2 interfaces IBasicCars and ILuxuryCars, IluxuryCars implementing IBasicCars and then in the second project I have a class that inherits from ILuxuryCars and implement all of its methods and IBasicCars methods and properties, here is my code for that class.
public class LuxuryCars : ILuxuryCar
{
private string _color { get; set; }
public string Color
{
get
{
return _color;
}
set
{
_color = value;
}
}
private int _model { get; set; }
public int Model
{
get
{
return _model;
}
set
{
_model = value;
}
}
private string _make { get; set; }
public string Make
{
get
{
return _make;
}
set
{
_make = value;
}
}
public void Break()
{
Console.WriteLine("This is the basic function of all cars !!!");
}
public void CruiseControl()
{
Console.WriteLine("This is the luxury feature for luxury cars !!!");
}
public void Drive()
{
Console.WriteLine("This is the basic function of all cars !!!");
}
public void Navigation()
{
Console.WriteLine("This is the luxury feature for luxury cars !!!");
}
public void Park()
{
Console.WriteLine("This is the basic function of all cars !!!");
}
}
now I have another class "FactoryObject" in that project that has nothing in it right now, can someone please tell me to do I implement the factory design pattern?
that is how I am calling these methods in main method
static void Main(string[] args)
{
ILuxuryCar lc = new LuxuryCars();
lc.Color = "Black";
lc.Make = "Honda";
lc.Model = 2007;
Console.WriteLine("Car color is: {0} Made by: {1} Model is: {2}", lc.Color, lc.Make, lc.Model);
lc.Navigation();
lc.CruiseControl();
lc.Break();
lc.Drive();
lc.Park();
Console.WriteLine();
IBasicCar b = new LuxuryCars();
b.Color = "Red";
b.Make = "Alto";
b.Model = 2019;
Console.WriteLine("Car color is: {0} Made by: {1} Model is: {2}", lc.Color, lc.Make, lc.Model);
lc.Break();
lc.Drive();
lc.Park();
Console.ReadLine();
}
A very simple factory could be
public interface ICarFactory{
ICar Create();
}
public class BasicCarFactory : ICarFactory{
public ICar Create() => new BasicCar();
}
public class LuxuryCarFactory : ICarFactory{
public ICar Create() => new LuxuryCar();
}
This makes it more complicated to create a car, but the important bit is that components that need to create new car objects can do so without knowing what kind of car is created.
You might for example check the license at startup, and depending on the license create different factories that you hand of to all the other components. This way you have the license check at one single place, instead of spread out over different components.
In simple cases you might not need a separate inteface, a Func<ICar> might be sufficient.
I have a basic architecture for 'orders' in my game - each order has a basic data type and an 'order processor' which performs some action based on the given data. For example 'move to this point.'
I'd like to have a tidy system where I can simply pass in order data and the correct order processor will kick in, in such a way that I can easily add new OrderData/OrderProcessor classes without modifying other classes or messing around with enums or casting, so it seems like generics are the way to go.
This is the current code I have. I'm drawing a blank for how to draw a connection in the 'OrderService' class between the correct 'OrderProcessor' and 'IOrderData' pairs. See inside the OrderService<T> class for more information:
public interface IOrderData
{
}
// an order processor reads data from an IOrderData object until the data object says stop
public abstract class OrderProcessor<T> where T : IOrderData
{
protected T m_currentData;
public virtual void Start(T data)
{
m_currentData = data;
}
}
////////////////////////
public class MoveOrderData : IOrderData
{
public Vector3 Destination { get; private set; }
}
public class MoveOrderProcessor : OrderProcessor<MoveOrderData>
{
public override void Start(MoveOrderData data)
{
base.Start(data);
}
}
////////////////////////
public class OrderService<T> where T : IOrderData
{
private Dictionary<System.Type, OrderProcessor<T>> m_processors = new Dictionary<System.Type, OrderProcessor<T>>();
private OrderProcessor<T> m_currentProcessor;
public void GiveOrder(IOrderData data)
{
// this is the main problem: I'm not sure how to say "the given data is type 'MoveOrderData' so find out which
// OrderProcessor class handles those and pass it in". A simple switch statement and cast would suffice here
// but I'd like to automate the process
}
}
A possible solution here can be a making an OrderService class non-generic, because it can handle a different types of orders/order processors (according to comments). Then maintain a Dictionary<Type, Action<object>>, which wraps Action<object> to call Start method from OrderProcessor<T>.
I've extended the original code a little bit to show how it can work
public interface IOrderData
{
}
public class MoveOrderData : IOrderData
{
public Vector3 Destination { get; private set; }
}
public class AttackOrderData : IOrderData
{
}
public abstract class OrderProcessor<T> where T : IOrderData
{
protected T CurrentData { get; set; }
public virtual void Start(T data)
{
CurrentData = data;
}
}
public class MoveOrderProcessor : OrderProcessor<MoveOrderData>
{
}
public class AttackOrderProcessor : OrderProcessor<AttackOrderData>
{
}
public class OrderService
{
private readonly Dictionary<Type, Action<object>> m_processors = new Dictionary<Type, Action<object>>();
public OrderService()
{
AddProcessor(new MoveOrderProcessor());
AddProcessor(new AttackOrderProcessor());
}
private void AddProcessor<T>(OrderProcessor<T> processor) where T : IOrderData
{
var action = (Action<T>)processor.Start;
m_processors.Add(typeof(T), obj => action((T)obj));
}
public void GiveOrder(IOrderData data)
{
var action = m_processors[data.GetType()];
action?.Invoke(data);
}
}
It causes a downcasting obj => action((T)obj), but it shouldn't be a problem, since your data is constrained to IOrderData interface. Example of the usage
var service = new OrderService();
service.GiveOrder(new MoveOrderData());
service.GiveOrder(new AttackOrderData());
Is it possible to limit object creation to methods of specific class?
For exemple: I have a class Transaction, and I would like to limit it object creation to methods of any class that inherits from AbstractService or IService:
Allowed Scenario:
public class ServiceA : AbstractService (or IService)
{
public void MethodA()
{
var transaction = new Transaction();
}
public void MethodB()
{
var transaction = new Transaction();
}
}
Prohibited Scenario:
public class ServiceB
{
public void MethodA()
{
var transaction = new Transaction(); // cannot create
}
public void MethodB()
{
var transaction = new Transaction(); // cannot create
}
}
There is a access modifier or something else that I can mount that scenarios?
There is a access modifier or something else that I can mount that scenarios?
Yes there is something else that can "mount" that scenario, but it's a lot of work and abstraction for, in my opinion, very little reward. This requires returning an interface of the Transaction, not a concrete type. (I'm pretty sure this works, I haven't compiled it however).
public abstract class AbstractService
{
}
public interface IService
{
}
public interface ITransaction
{
}
public static class TransactionFactory
{
// created them as extensions, but you could remove *this*
public static ITransaction CreateTransaction(this AbstractService instance)
{
return new Transaction ();
}
public static ITransaction CreateTransaction(this IService instance)
{
return new Transaction ();
}
private class Transaction : ITransaction
{
public Transaction ()
{
}
}
}
As a side note, someone technically could pass in null, so it would be best to do additional checking of the method parameters (however, that would be a runtime issue instead of a compile time issue).
If you wanted compile time checking I think you could do...
public interface ITransactionFactory { }
public abstract class AbstractService : ITransactionFactory { }
public interface IService : ITransactionFactory { }
public static class TransactionFactory<T>
where T : ITransactionFactory
{
public static ITransaction CreateTransaction(this T instance)
{
return new Transaction ();
}
// ....
Not quite sure if the second one works
The short answer is no, there is no access modifier which says "This object can only be constructed from a class which implements a specific interface".
You could code your way round this limitation, but its far from clean/foolproof.
public class Transaction
{
private Transaction(){} // private important!
public static Transaction Create(object creator)
{
if(creator is IService)
return new Transaction();
throw new InvalidOperationException();
}
}
public class ServiceA : IService
{
public void MethodA()
{
var transaction = Transaction.Create(this); // works
}
}
public class ServiceB
{
public void MethodA()
{
var transaction = Transaction.Create(this); // fails
}
}
It should be obvious how easily circumventable the above is. I suspect you have an XY Problem and you think this was the way to solve it.
Maybe I'm misunderstanding what you're trying to do, but it seems like this should do the trick:
public abstract class AbstractService : IService
{
protected class Transaction
{
}
}
public class ServiceA : AbstractService
{
public void MethodA()
{
var transaction = new Transaction();
}
public void MethodB()
{
var transaction = new Transaction();
}
}
public class ServiceB
{
public void MethodA()
{
var transaction = new Transaction(); // cannot create
}
public void MethodB()
{
var transaction = new Transaction(); // cannot create
}
}
internal interface IService
{
}
If you want anyone else to be able to use the Transaction, you'll need to have it implement some public interface or inherit it from another public class, but you can now ensure that no one else can create a Transaction object.
Is there an elegant (or any) way to achieve following in C#?
Let's have a class ItemBase (further derivable to Item1, Item2...), which does not allow direct instantiation (non-public construction) - to prevent user to create any 'untracked' instance of Item*.
Let's have a non-static class Manager, whose instances (multiple ones allowed) only can create and provide instances of Item* (because they keep track of produced instances and do some additional work).
Let's have an optional requirement: The Manager instances would like to manipulate non-public members of the managed Item instances (similar like the Manager would be a friend of Item*).
It would be nice if the Manager is not forced to be derivation of Item*.
It would be nice if there is as little reflection as possible.
Notes:
If possible, please consider this as a question raising from process of thinking how to implement particular problem solution in a best and elegant way. I would like it to be general and no, I don't have sources and yes, I have already tried some variants, but none of them satisfied my needs. Thank you.
As far as I know, there is no acceptable friend alternative (any of internal and InternalsVisibleToAttribute seems to be good), so the ItemBase just provides the 'special' (but public) modification methods and the user must be aware, these methods are not for him :o(
I like this solution, but I'm not able to invent, how to allow multiple Manager instances using it.
I think this might answer your problem :
public class ItemBase
{
protected ItemBase()
{
}
public void PublicMethod() { }
public int PublicProperty { get; set; }
}
public class Factory
{
private class PrivateItemBase : ItemBase
{
public void PrivateMethod() { }
public int PrivateProperty { get; set; }
}
public Factory(int id)
{
}
public IEnumerable<ItemBase> Items { get; private set; }
public ItemBase CreateItem()
{
PrivateItemBase rValue = new PrivateItemBase();
rValue.PrivateMethod();
rValue.PrivateProperty = 4;
return rValue;
}
}
Ok, giving up. If this might help to fully understand the purpose, there is the less bad solution I've (currently) ended up. Passing the creation functions is done via static constructors (which are not accessible by the users), unfortunately the ugly thing is their invocation...
Any idea how to make it better?
The item definitions:
namespace SpecialFactory
{
public enum ItemType
{
Item1,
Item2,
// ... Anyone deriving the Item* should add an item here
}
public abstract class ItemBase
{
public abstract ItemType Id {get;}
public static void RegisterAllCreators()
{
// Force static constructors invocation
var it = Item1.ClassId | Item2.ClassId; // Anyone deriving the Item* should ensure invocation of Manager.RegisterCreator
}
}
public class Item1 : ItemBase
{
static Item1()
{
Manager.RegisterCreator(ItemType.Item1, () => new Item1());
}
protected Item1()
{
}
public static ItemType ClassId => ItemType.Item1;
public override ItemType Id => ClassId;
}
public class Item2 : ItemBase
{
static Item2()
{
Manager.RegisterCreator(ItemType.Item2, () => new Item2());
}
protected Item2()
{
}
public static ItemType ClassId => ItemType.Item2;
public override ItemType Id => ClassId;
}
}
The manager:
namespace SpecialFactory
{
public class Manager
{
static Manager()
{
ItemBase.RegisterAllCreators();
}
protected static Dictionary<ItemType, Func<ItemBase>> creators = new Dictionary<ItemType, Func<ItemBase>>();
protected readonly List<ItemBase> managedItems = new List<ItemBase>();
protected ItemBase CreateItem(ItemType type)
{
ItemBase item = null;
if (creators.ContainsKey(type))
{
if ((item = creators[type]()) != null)
managedItems.Add(item);
}
return item;
}
public static void RegisterCreator(ItemType type, Func<ItemBase> creator)
{
if (!creators.ContainsKey(type))
creators[type] = creator;
}
public Manager()
{
}
public ItemBase Test(ItemType type)
{
// var notAllowed = new Item1();
var allowed = CreateItem(type);
return allowed;
}
}
}
The test:
namespace SpecialFactory
{
class Program
{
static void Main(string[] args)
{
var m1 = new Manager();
var m2 = new Manager();
var i1 = m1.Test(ItemType.Item1);
var i2 = m2.Test(ItemType.Item2);
}
}
}