在我们的一个项目中,我们有以下情形:我们有一个工厂,该工厂使用它的工厂来创建另一个包的服务(我们的工厂基本上是配置底层工厂)。基础工厂使用流利的语法,并且一个最小的示例如下所示:

public class SomeFactory<T> where T: class
{
    private readonly IFooService _fooService;
    private readonly IBarService<T> _barService;

    private readonly IUnderlyingFactory _factory;

    public SomeFactory(
        IFooService fooService, IBarService<T> barService, IUnderlyingFactory factory)
    {
        _fooService = fooService,
        _barService = barService,
        _factory = factory
    }

    public SomeService<T> Create()
    {
        return _factory
            .WithFooService(_fooService)
            .WithBarService(_barService)
            .Create();
    }
}


现在面临的问题是:对于某些T,我们已经实现了IBarService<T>。但是,基础包提供了一个默认实现(该内部实现是内部的,因此我们不能通用地注册它),以防万一我们没有该T的实现。在这种情况下,我们根本不应该调用.WithBarService方法。

但是,如果不注册IBarService<T>,则会从容器中获取异常,因为它无法解析它。

那么问题来了:当容器不能为某些IBarService<T>解析T时,是否可以配置该容器,使其返回null而不是抛出?还是有解决此问题的另一种方法?

万一收到null,可以将Create方法更改为:

public SomeService<T> Create()
{
    var service = _factory.WithFooService(_fooService);
    if (_barService != null){
        _factory.WithBarService(_barService);
    }
    return _factory.Create();
}


仅出于完整性考虑,这就是我们为某些BarService注册T的方式,即通过对实现类型的反思:

container.RegisterMany(
    ourAssembly.GetTypes()
        .Where(type => type.GetInterfaces().Any(i => i.IsGenericType
            && !type.IsAbstract)));

最佳答案

当无法为某些T解析IBarService时,是否可以配置容器使其返回null而不是抛出?还是有解决此问题的另一种方法?


您可以将IBarService<T>参数设置为可选,如果未注册服务,则不会抛出容器:

public SomeFactory( IFooService fooService, IUnderlyingFactory factory,
IBarService<T> barService = null) { _fooService = fooService, _barService = barService, _factory = factory }


或者,您可以使用IfUnresolved.ReturnDefault选项配置要注入的服务。

container.Register(typeof(SomeFactory<>),
  made: Parameters.Of.Type(typeof(IBarService<>), ifUnresolved: IfUnresolved.ReturnDefault))


注意:我可能会得到这最后一个错误的语法,但是应该正确无误。

09-13 02:01