【问题标题】:Resolving Generic Collections using AutoFac使用 AutoFac 解析通用集合
【发布时间】:2014-03-28 03:40:07
【问题描述】:

我找不到有关将集合解析为基类的问题。我有以下使用 AutoFac 解析处理程序的伪测试类:

namespace Test {

    interface IEventEmitter {}

    interface IEventHandler {}

    interface IEventHandler<in T> : IEventHandler where T: IEventEmitter {}

    interface ISomeClass : IEventEmitter {}

    class SomeClass : ISomeClass
    {
        // 2 handlers should be resolved here, not one!
        public SomeClass(IEnumerable<IEventHandler> handlers) {}
    }

    class GenericEventHandler : IEventHandler {}

    class DedicatedEventHandler : IEventHandler<ISomeClass> {}

    [TestClass]
    class TestClass
    {
        [TestMethod]
        private void TestHandlers()
        {
            var builder = new ContainerBuilder();

            // registered in order to resolve handlers
            builder.RegisterType<SomeClass>().As<ISomeClass>();

            builder.RegisterType<GenericEventHandler>().As<IEventHandler>();

            builder.RegisterType<DedicatedEventHandler>().As<IEventHandler<ISomeClass>>();

            var container = builder.Build();

            using (var scope = container.BeginLifetimeScope())
            {
                var instanceWithHandlers = scope.Resolve<ISomeClass>();
            }
        }
    }
}

请注意,我正在向 ISomeClass 接口注册一个专用处理程序,以及一个泛型 一个用于任何类型的事件发射器。我的期望是 SomeClass 构造函数将被注入 2 个处理程序——通用的和专用的。

不幸的是,事实并非如此。我在这里做错了什么?

谢谢。

【问题讨论】:

    标签: c# generics autofac


    【解决方案1】:

    当您向As 注册接口时,Autofac 不会自动注册其基本接口。

    所以你需要手动告诉 Autofac 你的 DedicatedEventHandler 也是一个 IEventHandler

    builder.RegisterType<DedicatedEventHandler>()
           .As<IEventHandler<ISomeClass>>()
           .As<IEventHandler>();
    

    如果你想用它的所有接口注册一个类型,你可以使用AsImplementedInterfaces 方法。

    所以上面注册的等价物如下:

    builder.RegisterType<DedicatedEventHandler>()
           .AsImplementedInterfaces();
    

    【讨论】:

    • 哦,顺便说一句-因为我们在这里注册了两个接口,所以 Dedicated 出现在任何 IEventHandler 集合中,对吗?有没有办法执行完整匹配以将分辨率限制为 SomeClass?
    • 是的 Dedicated 将在您请求 IEnumerable&lt;IEventHandler&gt; 的任何时候包含在内,因此您不能仅对 SomeClass 进行限制。 Autofac 不是上下文绑定中最好的,但您可以查看命名注册功能或github.com/autofac/Autofac/wiki/Typed-Named-And-Keyed-Services 或元数据支持:github.com/autofac/Autofac/wiki/Metadata
    • 是的,我想命名/键控服务会更好地工作,尽管我能够找到一种相当丑陋的方法来解决它。 builder.Register(c => new SomeClass(c.Resolve>() .Concat(c.Resolve>().Cast()))).As();
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多