.net - Autofac注册通过方法解决

标签 .net inversion-of-control autofac

我正在使用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/

相关文章:

c# - MVVM Light SimpleIoC 与 Ninject

c# - 在回调方法中获取输入参数

c# - ManualResetEventSlim 上的 Wait()-ing 是否保证在取消时抛出?

inversion-of-control - AOP 使用 Windsor 和批量注册类

php - Laravel Excel 安装

Autofac MVC与ASP.Net MVC 4的集成

c# - 使用 Autofac 将 log4net 注入(inject) Controller

c# - 为什么 Autofac 不调用我的类' `Dispose()` ?

c# - IoC比较

c# - 类我可以使用基类中 namespace 的属性吗