Здравствуйте, Abyx, Вы писали:
A>а вообще если использовать что-то типа DI-контейнера/сервис-локатора, то код получается довольно простым.
A>A>using MyDIContainer = std::tuple<Logger*, Config*, ...>;
A>class Foo {
A>public:
A> Foo(const MyDIContainer& di_container) {
A> auto cfg = get<Config*>(di_container); // std::get
A> ...
A> log(di_container, "something", 123); // calls "if (auto logger = get<Logger*>(di_container)) logger->log(args...);"
A> ...
A> auto bar = allocate<Bar>(di_container, 456); // calls "get<Allocator*>(di_container)->Create<T>(args...);"
A> };
A>};
A>
У тебя здесь обычный внешний параметр, пусть и составной.
IoC/DI-контейнер же это некоторый объект, как правило глобальный, который умеет создавать объекты требующие зависимости. Сами зависимые классы его не видят, и о нём ничего не знают.
Конкретные зависимости выбираются в соответствии с настроенными правилами — например можно указать что объекту Bar всегда давать логгер типа LoggerBar, или например внутри каждого потока (или даже соединения) использовать отдельный логгер.
Вот первый попавшийся
пример (с кучей опечаток
):
public interface IWeapon
{
void sord();
}
public class Ninja : IWeapon
{
public void sord()
{
Console.WriteLine("I am using Sord");
}
}
public class sourav
{
IWeapon ObjWeapon = null;
public sourav(IWeapon tmpWeapon)
{
this.ObjWeapon = tmpWeapon;
}
public void Attack()
{
this.ObjWeapon.sord();
}
}
class Program
{
static void Main(string[] args)
{
Ninject.IKernel kernal = new StandardKernel();
kernal.Bind<IWeapon>().To<Ninja>();
var instance = kernal.Get<sourav>();
instance.Attack();
Console.ReadLine();
}
}