从Autofac容器解析IEnumerable通用接口 [英] Resolving IEnumerable of generic interfaces from Autofac container

查看:97
本文介绍了从Autofac容器解析IEnumerable通用接口的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我不确定这是否可行,我已经看到其他一些帖子提出了类似的问题,但是没有一个令人满意的答案.

I'm not sure if this is possible, I've seen some other posts asking similar question but none have a satisfactory answer.

我想做的是解决与Autofac具有不同泛型类型的接口的集合.因此,类的构造函数将如下所示:

What I want to do is resolve a collection of interfaces with differing generic types from Autofac. So constructor of class would look something like this:

public class SomeClass<T> where T : class
{
    private readonly IEnumerable<ITestInterface<T>> _testInterfaces;

    public SomeClass(IEnumerable<ITestInterface<T>> testInterfaces)
    {
        _testInterfaces = testInterfaces;
    }
}

理想情况下,我希望能够像这样分别注册每个实例:

Ideally, I'd just like to be able to register each instance individually like so:

builder
    .RegisterType<ImplementationA>()
    .As<ITestInterface<A>>();

builder
    .RegisterType<ImplementationB>()
    .As<ITestInterface<B>>();

我尝试了RegisterGeneric等的各种组合,但是Enumerable一直保持空白.

I've tried various combinations of RegisterGeneric etc but the Enumerable just keeps coming through empty.

任何帮助将不胜感激.

推荐答案

在处理继承&后,我能够解决此问题.通用约束.我最终得到的解决方案如下:

I was able to resolve this after playing with inheritance & generic constraints. The solution I ended up with looks like this:

基类/接口:

public abstract class BaseClass
{
    public abstract string IAM { get; }
}

public interface ITestInterface<out T> where T : BaseClass
{
    T GetSomething();
}

实现的类:

public class A : BaseClass
{
    public override string IAM => "I AM TYPE A";
}

public class AInterface : ITestInterface<A>
{
    public A GetSomething()
    {
        return new A();
    }
}

public class B : BaseClass
{
    public override string IAM => "I AM TYPE B";
}

public class BInterface : ITestInterface<B>
{
    public B GetSomething()
    {
        return new B();
    }
}

我们要解决的课程:

public interface ISomeClass
{
    void DoSomething();
}

public class SomeClass<T> : ISomeClass where T : BaseClass
{
    private readonly IEnumerable<ITestInterface<T>> _testInterfaces;

    public SomeClass(IEnumerable<ITestInterface<T>> testInterfaces)
    {
        _testInterfaces = testInterfaces;
    }

    public void DoSomething()
    {
        foreach (var t in _testInterfaces)
        {
            var something = t.GetSomething();

            Console.WriteLine(something.IAM);
        }
    }
}

最后是Autofac配置:

And finally, Autofac configuration:

var builder = new ContainerBuilder();

builder
    .RegisterType<SomeClass<BaseClass>>()
    .AsSelf();

builder
    .RegisterType<AInterface>()
    .As<ITestInterface<BaseClass>>();

builder
    .RegisterType<BInterface>()
    .As<ITestInterface<BaseClass>>();

builder
    .RegisterType<SomeClass<BaseClass>>()
    .As<ISomeClass>();

var container = builder.Build();

var x = container.Resolve<ISomeClass>();

x.DoSomething();

输出:

我是A型

我是B型

希望这对以后的人有帮助.

Hope this helps someone in the future.

这篇关于从Autofac容器解析IEnumerable通用接口的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆