我正在一个具有大量模块的应用程序中调试 autofac 问题。有没有办法找出哪些模块注册了某些注册?我正在查看容器的 ComponentRegistry
,但在那里找不到任何信息。
编辑: 一个澄清。我的解决方案中有很多模块:
public class MyModule : Autofac.Module {
public override void Load(ContainerBuilder builder) {
builder.RegisterType<MyConcreteType>().As<IMyInterface>();
}
}
然后,我通过扫描我的程序集在我的容器中注册:
var builder = new ContainerBuilder();
builder.RegisterAssemblyModules(/* Get all assemblies in base dir */);
var container = builder.Build();
现在,我有很多注册。我的问题是“什么模块
注册了MyConcreteType
?”。我想做类似 container.ComponentRegistry.Registrations.Select(reg => new { reg.Service, reg.RegisteredBy })
的事情,其中 RegisteredBy
是一些神奇的属性.
最佳答案
好吧,我不是 100% 确定你的意思,但我会尝试一下:
为了调试,实现的类型显示在 ComponentRegistry 的 Registrations
集合中:
即在索引 0 处,实现类型为 CustomDataElement
。
可以在 ComponentRegistration
的 Services
集合中看到实现类型注册的服务类型。
这有帮助吗?你能举个例子吗?
编辑:
明白了...试试这个:
var l = _container.ComponentRegistry.Registrations
.SelectMany(r => r.Services.OfType<IServiceWithType>(),
(r, s) => new { r.Activator.LimitType, s.ServiceType });
不确定它是否按预期 100% 工作,但它应该可以帮助您...
编辑2:
我误解了这个问题,没有区分注册服务和注册模块。我认为不可能开箱即用,因为它要么需要将模块作为参数传递,要么需要 Autofac 在注册时反射(reflect)调用者。据我所知,两者都不是这样。我在 Autofac 中找不到任何内置功能。
如果您可以修改模块,一种方法是使用元数据注册类型。您可能知道这种方法,类似于
public class MyModule: Autofac.Module
{
public override void Load(ContainerBuilder builder)
{
builder.RegisterType<MyConcreteType>()
.As<IMyInterface>()
.WithMetadata<IRegisteredByModuleMetadata>(m =>
m.For(am => am.RegisteringModuleType, GetType());;
}
}
使用元数据接口(interface)
public interface IRegisteredByModuleMetadata
{
Type RegisteringModuleType { get; set; }
}
然后在容器中,使用元数据解析将允许通过注册 Metadata
属性访问模块类型。根据您的要求,您可以通过在自定义模块基类上提供 protected 类型注册方法来简化类型注册,该方法会自动附加元数据,因此您不必在此处重复。
如果可以选择修改解决方案中的每个模块,那么这可能不是一个坏方法。抱歉,我无法提供任何开箱即用的解决方案。可能有一个,我失踪了,但这就是我在这里能为你做的一切。希望它仍然有帮助。
关于c# - 找出哪个模块注册了类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22556647/