Question

I'm using Autofac constructor injection. I need to figure out how to inject a single object instance into more than one constructor argument, without needing to explicitly resolve each argument during the container setup phase.

I have a complex scenario which would be simplified by this behavior; the following example is just a simplified scenario so I can demonstrate the behavior I'm looking for.

Example:

Say I have these two interfaces, IOpenable and ICloseable:

public interface IOpenable
{
    void Open();
}
public interface ICloseable
{
    void Close();
}

And I have this Door class which implements both of them:

public interface IDoor : IOpenable, ICloseable { }
public class Door : IDoor, IOpenable, ICloseable 
{
    void Open() { ... }
    void Close() { ... }
}

And I have this class which accepts an IOpenable and an ICloseable:

public class DoorHandler : IDoorHandler
{
    public DoorHandler(IOpenable openable, ICloseable closeable)
    {
        ...
    }
    ...
}

Question:

Is it possible to tell autofac to inject the same Door object into both arguments whenever both an IOpenable and ICloseable are dependencies in the same constructor?

Note: I can't do:

container.Register<IDoorHandler>( c => {
    Door d = c.Resolve<IDoor>();
    return new DoorHandler(d,d)
});

That would do what I want, but remember that this DoorHandler class is just an example. In my real code, the "DoorHandler" is really an MVC Controller and I'm registering it with RegisterControllers(). So I can't register it like the above. Besides, sometimes dependency graphs can get overly complex and doing this explicitly in every case can become overwhelming.

I guess what I'm looking for is to be able to do something like:

container.RegisterType<DoorHandler>().As<IDoorHandler>();
container.RegisterType<Door>().As<IDoor>();
container.Register<IOpenable>( c => c.ResolveShared<IDoor>(); );
container.Register<ICloseable>( c => c.ResolveShared<IDoor>(); );

where calls to c.ResolveShared<T> will all resolve to the same T object if called for more than one argument in same constructor.

Or perhaps:

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>(); );

Obviously if I was using an InstancePerLifetimeScope or something for the Door object, each resolved Door would be the same instance. But I don't want that, I want a new instance of Door each time a DoorHandler is created, and I want that Door to be passed as both arguments to the DoorHandler constructor.

No correct solution

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top