如何正确设置 Autofac IIndex<K,V> 以在多租户容器中工作?
How to correctly set up Autofac IIndex<K,V> to work in a Multitenant container?
给定以下租户特定注册,当使用 Letter Factory(正确识别租户)时,IIndex 对象在索引时始终 return null。我已经验证程序集的过滤是正确的,并且每个字母都在 运行 时间被添加到索引中。所以我的问题是如何在不提取源代码并将其连接到我的项目并深入研究它的情况下解决这个问题?有没有办法在创建后验证容器,有点像 AutoMapper 在配置映射器时如何做?
谢谢,
斯蒂芬
仅供参考:
这是之前回答的下一个迭代
容器:
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;
}
}
我将它的一个简单的复制放在一起,它没有问题。
仔细查看您的代码,我认为问题出在这里:
if (attribute != null)
{
builder.RegisterType(letterType)
.Keyed<App.BusinessArea.NewBusiness.Letters.LetterBase>(attribute.LetterId);
}
这发生在多租户配置部分,但您没有在 lambda (b
) 中使用 ContainerBuilder
注册您的字母类型 -您正在使用一些 other ContainerBuilder
,可能是用于构建应用程序级容器的那个。 (如果这里包含整个容器配置而不仅仅是多租户部分,那么对于仔细阅读问题的人来说,这可能更容易发现。)
尝试切换到在 lambda 中使用 b.RegisterType...
。
给定以下租户特定注册,当使用 Letter Factory(正确识别租户)时,IIndex 对象在索引时始终 return null。我已经验证程序集的过滤是正确的,并且每个字母都在 运行 时间被添加到索引中。所以我的问题是如何在不提取源代码并将其连接到我的项目并深入研究它的情况下解决这个问题?有没有办法在创建后验证容器,有点像 AutoMapper 在配置映射器时如何做?
谢谢, 斯蒂芬
仅供参考:
这是之前回答的下一个迭代
容器:
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;
}
}
我将它的一个简单的复制放在一起,它没有问题。
仔细查看您的代码,我认为问题出在这里:
if (attribute != null)
{
builder.RegisterType(letterType)
.Keyed<App.BusinessArea.NewBusiness.Letters.LetterBase>(attribute.LetterId);
}
这发生在多租户配置部分,但您没有在 lambda (b
) 中使用 ContainerBuilder
注册您的字母类型 -您正在使用一些 other ContainerBuilder
,可能是用于构建应用程序级容器的那个。 (如果这里包含整个容器配置而不仅仅是多租户部分,那么对于仔细阅读问题的人来说,这可能更容易发现。)
尝试切换到在 lambda 中使用 b.RegisterType...
。