我正在使用CacheManager它使用工厂来创建实例。我不想注册我声明的每种类型的 ICacheManager,因此我正在寻找一种使用动态解析方法注册泛型类型的方法。使用 Ninject,我可以做到这一点:
kernel
.Bind(typeof(ICacheManager<>))
.ToMethod((context) => CacheFactory.FromConfiguration(context.GenericArguments[0], "defaultCache"))
.InSingletonScope();
其中 context.GenericArguments[0] 是我的泛型的类型。例如,来自
的对象ICacheManager<object> cache;
如何使用 Autofac 执行此类操作?
编辑
根据下面 Cyril 的答案工作 IRegistrationSource。 SingleInstance 是必需的,因为 CacheManager 在键前面添加了 CacheManager 实例 ID。
public class CacheManagerRegistrationSource : IRegistrationSource
{
public Boolean IsAdapterForIndividualComponents
{
get
{
return false;
}
}
public IEnumerable<IComponentRegistration> RegistrationsFor(Service service, Func<Service, IEnumerable<IComponentRegistration>> registrationAccessor)
{
IServiceWithType typedService = service as IServiceWithType;
if (typedService == null || !typedService.ServiceType.IsGenericType)
{
yield break;
}
Type cacheManagerType = typedService.ServiceType;
if (cacheManagerType.GetGenericTypeDefinition() != typeof(ICacheManager<>))
{
yield break;
}
IComponentRegistration registration = (IComponentRegistration)RegistrationBuilder.ForDelegate(cacheManagerType, (c, p) =>
{
return CacheFactory.FromConfiguration(cacheManagerType.GetGenericArguments()[0], "defaultCache");
})
.SingleInstance()
.CreateRegistration();
yield return registration;
}
}
最佳答案
默认情况下,Autofac 不允许检索正在注册的对象的通用类型。没有简单的内置方法可以做到这一点,但您可以使用 IRegistrationSource
来实现您想要的:
public class CacheManagerRegistrationSource : IRegistrationSource
{
public Boolean IsAdapterForIndividualComponents
{
get
{
return false;
}
}
public IEnumerable<IComponentRegistration> RegistrationsFor(Service service, Func<Service, IEnumerable<IComponentRegistration>> registrationAccessor)
{
IServiceWithType typedService = service as IServiceWithType;
if (typedService == null)
{
yield break;
}
Type cacheManagerType = typedService.ServiceType
.GetInterfaces()
.Where(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(ICacheManager<>))
.FirstOrDefault();
if (cacheManagerType == null)
{
yield break;
}
IComponentRegistration registration =
RegistrationBuilder.ForDelegate(cacheManagerType, (c, p) => {
return CacheFactory.FromConfiguration(cacheManagerType.GetGenericArguments()[0], "defaultCache");
})
.SingleInstance()
.CreateRegistration();
yield return registration;
}
}
那么您必须通过执行以下操作来注册注册源:
builder.RegisterSource(new CacheManagerRegistrationSource());
这是 RegisterGeneric
方法内部工作的方式。
关于.net - Autofac注册通过方法解决,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33898991/