如何正确设置Autofac IIndex <k,v>以在多租户容器中工作?

时间:2018-05-17 18:10:59

标签: c# autofac

鉴于以下租户特定注册,当使用Letter Factory(正确识别租户)时,IIndex对象在索引时始终返回null。我已经验证过程序集的过滤是正确的,并且每个字母都在运行时添加到索引中。所以我的问题是如何在不拉动源并将其连接到我的项目并通过它进行故障排除的情况下对此进行故障排除?有没有办法在创建后验证容器,有点像AutoMapper在配置映射器时的工作方式?

谢谢你, 斯蒂芬

供参考:

这是之前回答的question

的下一次迭代

集装箱:

mtc.ConfigureTenant("1",
    b =>
    {
        List<Type> letterTypes = typeof(App.BusinessArea.NewBusiness.Letters.LetterBase).Assembly.GetTypes()
            .Where(t => !t.IsAbstract && t.IsSubclassOf(typeof(App.BusinessArea.NewBusiness.Letters.LetterBase)))
            .Where(t => t.GetCustomAttributes(typeof(LetterTypeAttribute), false).Length == 1)
            .ToList();

        foreach (Type letterType in letterTypes)
        {
            LetterTypeAttribute attribute = letterType.GetCustomAttributes<LetterTypeAttribute>()
                .FirstOrDefault();

            if (attribute != null)
            {
                builder.RegisterType(letterType)
                    .Keyed<App.BusinessArea.NewBusiness.Letters.LetterBase>(attribute.LetterId);
            }
        }


        b.RegisterType<App.BusinessArea.NewBusiness.Letters.LetterFactory>()
            .As<App.BusinessArea.NewBusiness.Letters.ILetterFactory>();

        b.RegisterType<App.BusinessArea.NewBusiness.DocumentServices>()
            .As<IDocumentServices>();
    });

mtc.ConfigureTenant("2", 
    b =>
    {
        List<Type> letterTypes = typeof(App.BusinessArea.Claims.Letters.LetterBase).Assembly.GetTypes()
            .Where(t => !t.IsAbstract && t.IsSubclassOf(typeof(App.BusinessArea.Claims.Letters.LetterBase)))
            .Where(t => t.GetCustomAttributes(typeof(LetterTypeAttribute), false).Length == 1)
            .ToList();

        foreach(Type letterType in letterTypes)
        {
            LetterTypeAttribute attribute = letterType.GetCustomAttributes<LetterTypeAttribute>()
                .FirstOrDefault();

            if(attribute != null)
            {
                builder.RegisterType(letterType)
                    .Keyed<App.BusinessArea.Claims.Letters.LetterBase>(attribute.LetterId);
            }
        }

        b.RegisterType<App.BusinessArea.Claims.Letters.LetterFactory>()
            .As<App.BusinessArea.Claims.Letters.ILetterFactory>();

        b.RegisterType<App.BusinessArea.Claims.DocumentService>()
            .As<IDocumentServices>();
    });

每个租户的工厂:

public class LetterFactory : ILetterFactory
{
    private readonly IIndex<int, LetterBase> _lettersFactory;

    public LetterFactory(IIndex<int, LetterBase> lettersFactory)
    {
        _lettersFactory = lettersFactory;
    }

    public LetterBase Create(int letterId)
    {
        if (letterId <= 0)
        {
            throw new ArgumentOutOfRangeException(nameof(letterId));
        }


        LetterBase letter = null; 
        if(!_lettersFactory.TryGetValue(letterId, out letter))
        {
            string message = $"Could not find a Letter to create for id {letterId}.";
            throw new NotSupportedException(message);        
        }
        return letter;
    }
}

1 个答案:

答案 0 :(得分:1)

我把这个简单的复制品放在一起,它没有问题。

仔细观察您的代码我认为问题在于:

if (attribute != null)
{
  builder.RegisterType(letterType)
         .Keyed<App.BusinessArea.NewBusiness.Letters.LetterBase>(attribute.LetterId);
}

在多租户配置部分中发生,但您没有在lambda(ContainerBuilder)中使用b注册您的字母类型 - 您正在使用某些其他 ContainerBuilder,可能是用于构建应用程序级容器的那个。 (如果整个容器配置包含在这里而不仅仅是多租户部分,那么人们可能更容易理解这个问题。)

尝试切换到lambda中使用b.RegisterType...