Я использую инъекцию конструктора Autofac. Мне нужно выяснить, как внедрить один экземпляр объекта в несколько аргументов конструктора, без необходимости явно разрешать каждый аргумент на этапе настройки контейнера.
У меня сложный сценарий, который будет упрощен этим поведением; следующий пример - просто упрощенный сценарий, поэтому я могу продемонстрировать искомое поведение.
Пример:
Допустим, у меня есть два интерфейса: IOpenable и ICloseable:
public interface IOpenable
{
void Open();
}
public interface ICloseable
{
void Close();
}
И у меня есть класс Door, который реализует их оба:
public interface IDoor : IOpenable, ICloseable { }
public class Door : IDoor, IOpenable, ICloseable
{
void Open() { ... }
void Close() { ... }
}
И у меня есть этот класс, который принимает IOpenable и ICloseable:
public class DoorHandler : IDoorHandler
{
public DoorHandler(IOpenable openable, ICloseable closeable)
{
...
}
...
}
Вопрос:
Можно ли сказать autofac, что нужно вводить один и тот же Door объект в оба аргумента, когда оба IOpenable и ICloseable являются зависимостями в одном конструкторе?
Примечание: я не могу сделать :
container.Register<IDoorHandler>( c => {
Door d = c.Resolve<IDoor>();
return new DoorHandler(d,d)
});
То, что будет делать то, что я хочу, но помните, что этот класс DoorHandler является лишь примером. В моем реальном коде «DoorHandler» действительно является контроллером MVC, и я регистрирую его с помощью RegisterControllers (). Поэтому я не могу зарегистрировать это, как указано выше. Кроме того, иногда графы зависимостей могут быть чрезмерно сложными, и выполнение этого явно в каждом случае может стать чрезмерным.
Полагаю, мне нужно сделать что-то вроде:
container.RegisterType<DoorHandler>().As<IDoorHandler>();
container.RegisterType<Door>().As<IDoor>();
container.Register<IOpenable>( c => c.ResolveShared<IDoor>(); );
container.Register<ICloseable>( c => c.ResolveShared<IDoor>(); );
где вызовы c.ResolveShared<T>
преобразуются в один и тот же объект T, если вызывается для более чем одного аргумента в одном конструкторе.
Или, возможно:
container.RegisterType<DoorHandler>().As<IDoorHandler>();
container.RegisterType<Door>().As<IDoor>().InstancePerDependencyShared();
container.Register<IOpenable>( c => c.Resolve<IDoor>(); );
container.Register<ICloseable>( c => c.Resolve<IDoor>(); );
Очевидно, что если бы я использовал InstancePerLifetimeScope или что-то для объекта Door, каждая разрешенная Door была бы одним и тем же экземпляром. Но я не хочу этого, я хочу новый экземпляр Door каждый раз, когда создается DoorHandler, и я хочу, чтобы эта Door передавалась как оба аргумента конструктору DoorHandler.