注册馆藏时重写生活方式?

时间:2015-11-12 20:18:40

标签: c# dependency-injection ioc-container simple-injector

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

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。我需要将它们注册为一个集合,我正在这样做:

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

虽然可行,但由于IDisposable而导致Transient设置所需的错误。好的,我明白了,我看到有一个例子可以在注册单个项目时解决这个问题:

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));
}

对于集合的错误抑制是否没有覆盖?我无法获得任何可以抑制诊断警告的工作,在验证容器时我们会忽略它,并且我总是收到有关瞬态和{{1}的错误/警告}。我如何注册一个集合,让容器知道我得到它,我需要抑制错误?使用上面的IDisposable注册单个API控制器工作正常,但由于两个实现在一个服务上,我需要使用该集合。

1 个答案:

答案 0 :(得分:2)

只需执行以下操作,一切都应该正常工作:

container.RegisterWebApiControllers(GlobalConfiguration.Configuration);

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

这将起作用的原因是:

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

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

如果这两个ApiControllers没有使用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)
});