Предположим, у меня есть интерфейс для службы:
public interface IFooService
{
void DoSomething();
}
И конкретная реализация этого сервиса, который является общим:
public class FooService<TRequestingClass> : IFooService
{
public virtual void DoSomething() { }
}
И у меня есть другой класс, которому нужен экземпляр IFooService:
public class Bar
{
private IFooService _fooService;
public Bar(IFooService fooService)
{
this._fooService = fooService;
}
}
Мне нужно подключить свой контейнер IoC так, чтобы при создании Bar ему передавался аргумент конструктора FooService . Есть много других классов, таких как Бар. Каждому из них также может понадобиться экземпляр FooService , переданный им, где TRequestingClass - это тип класса, которому требуется экземпляр IFooService. Мне не нужно раскрывать эту причуду для потребителей IFooService. Все, о чем они должны заботиться, - это то, что они могут вызывать методы IFooService, которые они передали. Им не нужно знать, что конкретная реализация IFooService, которую они передали, нуждается в создании чего-то особенного.
Приемлемой альтернативой FooService будет класс, не являющийся универсальным, со строковым аргументом в своем конструкторе, который содержит имя класса, для которого он создается. то есть:
public class FooService : IFooService
{
public FooService(string requestingClassName) { }
}
Как я могу подключить свой контейнер IoC для создания зависимости таким образом?
Если вы не уверены, почему мне нужна такая странная структура, подумайте, как лучше всего работает log4net, когда вы получаете ILog, который создается с помощью log4net.LogManager.GetLogger (typeof (SomeClass)). Я не хочу засорять свой код ссылками на log4net, поэтому я хотел бы написать простой интерфейс ILogger и реализовать его примерно так:
public class GenericLogger<T> : ILogger
{
private readonly ILog log;
public GenericLogger()
{
this.log = log4net.LogManager.GetLogger(typeof(T));
}
public void Debug(object message)
{
this.log.Debug(message);
}
/* .... etc .... */
}