【问题标题】:Autofac with Open Generics and Type Specified at Runtime运行时指定的具有开放泛型和类型的 Autofac
【发布时间】:2010-12-04 03:30:21
【问题描述】:

文档指出 Autofac 支持开放泛型,我能够在这样的基本情况下注册和解析:

注册:

builder.RegisterGeneric(typeof(PassThroughFlattener<>))
       .As(typeof(IFlattener<>))
       .ContainerScoped();

解决:

var flattener = _container.Resolve<IFlattener<Address>>();

上面的代码工作得很好。但是,假设我直到运行时才知道提供给 IFlatener 的类型,我想做这样的事情:

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

我正在努力实现本文中概述的相同目标。

【问题讨论】:

    标签: dependency-injection ioc-container autofac


    【解决方案1】:

    这当然可以使用 Autofac。在“注册时间”,这就是你基本上要做的事情:

    1. 注册开放的泛型类型(PassThroughFlatener)
    2. 注册任何特定类型 (AddressFlatener)
    3. 注册一个可用于基于输入对象解析 IFlatener 的方法

    在“解决时间”,你会做:

    1. 解决方法
    2. 使用输入参数调用方法以解析 IFlatener 实现

    这是一个(希望如此)工作示例:

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

    【讨论】:

      【解决方案2】:

      如果您直到运行时才知道类型,您可以使用 MakeGenericType 构建它:

      var addressFlattener = _container.Resolve(typeof(IFlattener<>).MakeGenericType(typeof(Address)));
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-06-10
        相关资源
        最近更新 更多