注册 Collection 时覆盖生活方式?

Overriding Lifestyle when Registering a Collection?

我的配置需要注册两个控制器,它们很简单:

public class DataApiController : ApiController
{
    readonly Data _data;
    readonly MongoRepo _mongoRepo;
    readonly JobManager _jobManager;
    readonly QueueManager _queueManager;

    public DataApiController(QueueManager queueManager, 
        MongoRepo mongoRepo, JobManager jobManager, Data data)
    {
        _queueManager = queueManager;
        _mongoRepo = mongoRepo;
        _jobManager = jobManager;
        _data = data;
    }

    ...           
}

和另一个也使用 ApiController。我需要将它们注册为 collection,我正在这样做:

var types = new[] { typeof(DataApiController), typeof(BatchApiController) };
container.RegisterCollection<ApiController>(
    from type in types
    select Lifestyle.Transient.CreateRegistration(type, container));

虽然这有效,但我收到错误消息,由于 IDisposable,所需的瞬态设置有误。好的,我明白了,我看到有一个在注册单个项目时解决这个问题的例子:

public static void RegisterDisposableTransient<TService, TImplementation>(
    this Container container)
    where TImplementation : class, IDisposable, TService
    where TService : class
{
    var scoped = Lifestyle.Scoped;
    var reg = Lifestyle.Transient.CreateRegistration<TService, TImplementation>(container);
    reg.SuppressDiagnosticWarning(DiagnosticType.DisposableTransientComponent,
    "suppressed.");
    container.AddRegistration(typeof(TService), reg);
    container.RegisterInitializer<TImplementation>(
        o => scoped.RegisterForDisposal(container, o));
}

是否没有覆盖 collection 的错误抑制?我无法得到任何抑制诊断警告的工作,就像在验证容器时它只是被忽略一样,我总是得到关于 Transient 和 IDisposable 的 error/warning。我怎样才能注册一个 collection 并让容器知道我得到它并且我需要抑制错误?使用上面的 RegisterDisposableTransient 注册单个 API 控制器工作正常,但由于一项服务的两个实现,我需要使用 collection。

只需执行以下操作,一切都会正常进行:

container.RegisterWebApiControllers(GlobalConfiguration.Configuration);

container.RegisterCollection<ApiController>(new[] {
    typeof(DataApiController), typeof(BatchApiController)
});

之所以可行,是因为:

  • RegisterWebApiControllers 将使用 Transient 生活方式(通过它们的具体类型)注册所有应用程序的控制器,并将对该注册添加抑制。
  • 简单注入器会将使用 RegisterCollection 注册的任何(具体)类型转发回容器,并将重用任何现有注册。

这导致 DataApiControllerBatchApiController(使用 RegisterWebApiControllers 注册)的现有注册被重复使用,包括它们的抑制。

如果这两个 ApiController 未使用 RegisterWebApiControllers 注册(可能是因为它们在不同的程序集中),以下方法也可以解决问题:

var r1 = Lifestyle.Transient.CreateRegistration<DataApiController>(container);
r1.SuppressDiagnosticWarning(DiagnosticType.DisposableTransientComponent, 
    "done by web api");

container.AddRegistration(typeof(DataApiController), r1);

var r2 = Lifestyle.Transient.CreateRegistration<BatchApiController>(container);
r2.SuppressDiagnosticWarning(DiagnosticType.DisposableTransientComponent, 
    "done by web api");

container.AddRegistration(typeof(BatchApiController), r2);

container.RegisterCollection<ApiController>(new[] {
    typeof(DataApiController), typeof(BatchApiController)
});