DryIoc ScopedTo 现在包括父作用域?

DryIoc ScopedTo now includes parent scope?

下面的代码适用于 DryIoc 2.x。我刚刚更新到 4.x。该代码不再有效(请参阅下面的例外情况)。似乎 4.x 将“ScopedTo”数据视为非排他性的,而在 2.x 中,它们是范围独有的——它们不可用于开箱即用的其他范围。我现在如何获得 2.x 行为?异常列出了几种补救措施,但哪种补救措施符合 2.x 行为?

using System;
using DryIoc;

namespace TestDryIoc
{
    public interface IDep {}

    public interface IOwner
    {
        IDep Dep { get; }
    }
    
    public class Dep1: IDep {}
    public class Dep2: IDep {}

    public class Owner1: IOwner
    {
        public Owner1(IDep dep)
        {
            Dep = dep;
        }
        
        public IDep Dep { get; }
    }

    public class Owner2: IOwner
    {
        public Owner2(IDep dep)
        {
            Dep = dep;
        }
        
        public IDep Dep { get; }
    }
    
    class Program
    {
        static void Main(string[] args)
        {
            var container = new Container();
            container.Register<IDep, Dep1>(Reuse.InResolutionScopeOf<Owner1>());
            container.Register<IDep, Dep2>(Reuse.InResolutionScopeOf<Owner2>());
            
            container.RegisterMany<Owner1>(Reuse.Singleton, setup: Setup.With(openResolutionScope: true));
            container.RegisterMany<Owner2>(Reuse.Singleton, setup: Setup.With(openResolutionScope: true));

            container.Resolve<Owner2>();
        }
    }
}

我在 v4.2.3 中得到的异常:

DryIoc.ContainerException: code: ExpectedSingleDefaultFactory; message: Expecting single default registration but found many:
(DefaultKey(0), {FactoryID=144, ImplType=TestDryIoc.Dep1, Reuse=Scoped {Name={ServiceType=TestDryIoc.Owner1}, Lifespan=100}}), 
(DefaultKey(1), {FactoryID=145, ImplType=TestDryIoc.Dep2, Reuse=Scoped {Name={ServiceType=TestDryIoc.Owner2}, Lifespan=100}, AsResolutionCall})
when resolving Resolution call dependency TestDryIoc.IDep (IsSingletonOrDependencyOfSingleton, IsResolutionCall)
  in Resolution root Singleton TestDryIoc.Owner2 FactoryId=147 (IsSingletonOrDependencyOfSingleton, IsResolutionCall)
  from container without scope.
Please identify service with key, or metadata, or use Rules.WithFactorySelector to specify single registered factory.
  at DryIoc.Throw.It(Int32 error, Object arg0, Object arg1, Object arg2, Object arg3) in /_/src/DryIoc/Container.cs:12902
  at DryIoc.Container.DryIoc.IContainer.GetServiceFactoryOrDefault(Request request) in /_/src/DryIoc/Container.cs:1217
  at DryIoc.Container.DryIoc.IContainer.ResolveFactory(Request request) in /_/src/DryIoc/Container.cs:1039
  at DryIoc.Container.ResolveAndCacheKeyed(Int32 serviceTypeHash, Type serviceType, Object serviceKey, IfUnresolved ifUnresolved, Object scopeName, Type requiredServiceType, Request preResolveParent, Object[] args) in /_/src/DryIoc/Container.cs:468
  at DryIoc.Container.DryIoc.IResolver.Resolve(Type serviceType, Object serviceKey, IfUnresolved ifUnresolved, Type requiredServiceType, Request preResolveParent, Object[] args) in /_/src/DryIoc/Container.cs:427
  at DryIoc.Interpreter.InterpretResolveMethod(IResolverContext resolver, IList`1 callArgs, Object paramExprs, Object paramValues, ParentLambdaArgs parentArgs, Boolean useFec, Object& result) in /_/src/DryIoc/Container.cs:3502
  at DryIoc.Interpreter.TryInterpretMethodCall(IResolverContext r, Expression expr, Object paramExprs, Object paramValues, ParentLambdaArgs parentArgs, Boolean useFec, Object& result) in /_/src/DryIoc/Container.cs:3386
  at DryIoc.Interpreter.TryInterpret(IResolverContext r, Expression expr, Object paramExprs, Object paramValues, ParentLambdaArgs parentArgs, Boolean useFec, Object& result) in /_/src/DryIoc/Container.cs:2915
  at DryIoc.Interpreter.TryInterpret(IResolverContext r, Expression expr, Object paramExprs, Object paramValues, ParentLambdaArgs parentArgs, Boolean useFec, Object& result) in /_/src/DryIoc/Container.cs:2818
  at DryIoc.Interpreter.TryInterpretAndUnwrapContainerException(IResolverContext r, Expression expr, Boolean useFec, Object& result) in /_/src/DryIoc/Container.cs:2753
  at DryIoc.Factory.ApplyReuse(Expression serviceExpr, Request request) in /_/src/DryIoc/Container.cs:9825
  at DryIoc.Factory.GetExpressionOrDefault(Request request) in /_/src/DryIoc/Container.cs:9734
  at DryIoc.Container.ResolveAndCacheKeyed(Int32 serviceTypeHash, Type serviceType, Object serviceKey, IfUnresolved ifUnresolved, Object scopeName, Type requiredServiceType, Request preResolveParent, Object[] args) in /_/src/DryIoc/Container.cs:499
  at DryIoc.Container.DryIoc.IResolver.Resolve(Type serviceType, Object serviceKey, IfUnresolved ifUnresolved, Type requiredServiceType, Request preResolveParent, Object[] args) in /_/src/DryIoc/Container.cs:427
  at DryIoc.Interpreter.InterpretResolveMethod(IResolverContext resolver, IList`1 callArgs, Object paramExprs, Object paramValues, ParentLambdaArgs parentArgs, Boolean useFec, Object& result) in /_/src/DryIoc/Container.cs:3502
  at DryIoc.Interpreter.TryInterpretMethodCall(IResolverContext r, Expression expr, Object paramExprs, Object paramValues, ParentLambdaArgs parentArgs, Boolean useFec, Object& result) in /_/src/DryIoc/Container.cs:3386
  at DryIoc.Interpreter.TryInterpret(IResolverContext r, Expression expr, Object paramExprs, Object paramValues, ParentLambdaArgs parentArgs, Boolean useFec, Object& result) in /_/src/DryIoc/Container.cs:2915
  at DryIoc.Interpreter.TryInterpretAndUnwrapContainerException(IResolverContext r, Expression expr, Boolean useFec, Object& result) in /_/src/DryIoc/Container.cs:2753
  at DryIoc.Container.ResolveAndCache(Int32 serviceTypeHash, Type serviceType, IfUnresolved ifUnresolved) in /_/src/DryIoc/Container.cs:406
  at DryIoc.Container.DryIoc.IResolver.Resolve(Type serviceType, IfUnresolved ifUnresolved) in /_/src/DryIoc/Container.cs:353
  at DryIoc.Resolver.Resolve[TService](IResolver resolver, IfUnresolved ifUnresolved) in /_/src/DryIoc/Container.cs:7580
  at TestDryIoc.Program.Main(String[] args) in ```

似乎是一个错误。我在 DryIoc 存储库 https://github.com/dadhi/DryIoc/issues/290 中创建了相应的问题。请把讨论移到那里。

只有 Reuse.Singleton 父服务才会出现此问题。因此,在问题得到解决之前,解决方法可能是更改 Owner 重用或插入人工作用域以扮演这些服务的单例角色。

更新

带有修复程序的 DryIoc v4.2.4 已在 NuGet 上发布 https://github.com/dadhi/DryIoc/releases/tag/v4.2.4