Recently, Castle added support for interface factories with implementations provided by the kernel. I am wondering if there is a way to do this in autofac also. I have read about the delegate factories, but I think I might be missing something, and am unable to get it to work. Here is what I am thinking:
class Message { }
interface IHandle<T> {
void Handle(T message);
}
class Handle<Message> : IHandle<Message> {
...
}
class Bus {
.ctor (? lookup) {
_lookup = lookup;
}
void Send<T>(T message) {
_lookup.GetHandler<T>().Handle(message);
}
}
var builder = new ContainerBuilder();
builder.RegisterType<Handle<Message>>().As<IHandle<Message>>();
builder.RegisterType<Bus>();
var container = builder.Build();
container.Resolve<Bus>().Send<Message>(new Message());
What I’m trying to do is keep the container out of the bus (as I agree that service locator is an anti-pattern) or any other implementation. This problem is easy if I just feed the container to the bus, or create some class factory that wraps the container. Just trying to make sure there isn’t a way to do this already.
Btw, the castle way iirc allows me to register something like this:
interface IHandlerFactory {
IHandle<T> GetHandler<T>();
}
container.Register<IHandlerFactory>().AsFactory();
Thanks,
Nick
You could isolate that coupling by creating a concrete
IHandlerFactory, sayAutofacHandlerFactory, which would receive theILifetimeScope. That coupling seems inevitable since the container is the only one who can resolve the properIHandler<T>.Coupling with
ILifetimeScopemight be a bad idea, but then, the coupling is isolated inside the concreteIHandlerFactory, and theBusjust uses it through an interface. Let’s say you change the container and starts using Ninject, you could just implement aNinjectHandlerFactoryto do the job.