文档指出 Autofac 支持开放泛型,我能够在基本情况下进行注册和解析,如下所示:
登记:
builder.RegisterGeneric(typeof(PassThroughFlattener<>))
.As(typeof(IFlattener<>))
.ContainerScoped();
解决:
var flattener = _container.Resolve<IFlattener<Address>>();
上面的代码工作得很好。但是,假设直到运行时我才知道提供给 IFlattener 的类型,我想做这样的事情:
object input = new Address();
var flattener = (IFlattener)_container.Resolve(typeof(IFlattener<>), new TypedParameter(typeof(IFlattener<>), input.GetType()));
这可以用 AutoFac 实现吗?我从以下使用 StructureMap 得到了这个想法:
http://structuremap.sourceforge.net/Generics.htm
我正在努力实现本文中概述的相同目标。
最佳答案
Autofac当然可以做到这一点。在“注册时间”,这就是您的基本操作:
在“解决时间”,您将执行以下操作:
这是一个(希望如此)工作示例:
var openType = typeof(IFlattener<>);
var builder = new ContainerBuilder();
builder.RegisterGeneric(typeof(PassThroughFlattener<>)).As(openType);
builder.Register<AddressFlattener>().As<IFlattener<Address>>();
builder.Register<Func<object, IFlattener>>(context => theObject =>
{
var closedType =
openType.MakeGenericType(theObject.GetType());
return (IFlattener) context.Resolve(closedType,
new PositionalParameter(0, theObject));
});
var c = builder.Build();
var factory = c.Resolve<Func<object, IFlattener>>();
var address = new Address();
var addressService = factory(address);
Assert.That(addressService, Is.InstanceOfType(typeof(AddressFlattener)));
var anything = "any other data";
var anyService = factory(anything);
Assert.That(anyService, Is.InstanceOfType(typeof(PassThroughFlattener<string>)));
关于dependency-injection - 具有开放泛型和运行时指定类型的 Autofac,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1523336/