You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为基于IInteractor的自定义接口批量注册Autofac泛型装饰器?

给自定义交互器接口批量注册Autofac泛型装饰器的方案

核心逻辑

你的自定义接口(比如IGetFoobar)都继承自具体的IInteractor<TRequest, TResponse>闭包泛型,所以只要通过Autofac的约定扫描找到所有这类自定义接口,就能统一为它们绑定InteractorLoggingDecorator<,>装饰器。

具体实现

1. 保留原有的交互器批量注册

确保交互器类同时注册到自身实现的自定义接口和基础IInteractor<,>接口:

builder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly())
       .Where(t => t.Name.EndsWith("Interactor"))
       .AsImplementedInterfaces()
       .InstancePerLifetimeScope();

2. 批量为自定义接口注册装饰器

有两种写法可选:

写法一:遍历筛选自定义接口

手动扫描程序集里所有符合条件的自定义接口,逐个注册装饰器:

var baseInteractorType = typeof(IInteractor<,>);
// 找出所有继承自IInteractor<,>闭包泛型的自定义接口
var customInterfaces = Assembly.GetExecutingAssembly()
    .GetTypes()
    .Where(t => t.IsInterface 
                && !t.IsGenericTypeDefinition 
                && t.GetInterfaces().Any(i => 
                    i.IsGenericType && i.GetGenericTypeDefinition() == baseInteractorType));

foreach (var customInterface in customInterfaces)
{
    // 获取该自定义接口对应的IInteractor泛型参数
    var matchedInteractor = customInterface.GetInterfaces()
        .First(i => i.GetGenericTypeDefinition() == baseInteractorType);
    var requestType = matchedInteractor.GetGenericArguments()[0];
    var responseType = matchedInteractor.GetGenericArguments()[1];

    // 构造对应的装饰器类型
    var decoratorType = typeof(InteractorLoggingDecorator<,>).MakeGenericType(requestType, responseType);
    
    // 为自定义接口注册装饰器
    builder.RegisterDecorator(decoratorType, customInterface);
}

写法二:用Autofac的装饰器条件匹配

通过RegisterDecorator的重载,直接筛选符合条件的服务类型,自动应用装饰器:

builder.RegisterDecorator(
    (ctx, decoratedInstance) => 
    {
        // 从被装饰实例中拿到对应的IInteractor泛型信息
        var interactorInterface = decoratedInstance.GetType()
            .GetInterfaces()
            .First(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IInteractor<,>));
        var genericArgs = interactorInterface.GetGenericArguments();
        // 构造装饰器实例
        return Activator.CreateInstance(
            typeof(InteractorLoggingDecorator<,>).MakeGenericType(genericArgs),
            decoratedInstance
        );
    },
    // 筛选条件:是接口、不是IInteractor<,>本身、且继承自IInteractor<,>
    serviceType => serviceType.IsInterface 
                   && serviceType != typeof(IInteractor<,>)
                   && serviceType.GetInterfaces().Any(i => 
                       i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IInteractor<,>))
);

注意事项

  • 自定义接口必须继承具体的闭包泛型IInteractor<TReq, TRes>,不能直接继承泛型定义IInteractor<,>
  • 装饰器的注册代码一定要放在交互器注册代码之后,不然Autofac找不到要装饰的服务

内容的提问来源于stack exchange,提问作者user13842370

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 23:31:13