DryIo c ScopedTo теперь включает родительскую область? - PullRequest
1 голос
/ 13 июля 2020

Приведенный ниже код работал в DryIo c 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>();
        }
    }
}

Исключение, которое я получаю в версии 4.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 ```

1 Ответ

0 голосов
/ 14 июля 2020

Похоже на ошибку. Я создал соответствующую проблему в репозитории DryIo c https://github.com/dadhi/DryIoc/issues/290. Переместите обсуждение туда.

Проблема появится только с Reuse.Singleton родительскими службами. Поэтому, пока проблема не будет устранена, временным решением может быть изменение Owner повторного использования или вставка искусственной области видимости, чтобы играть роль синглтона для этих служб.

Обновление

DryIo c v4.2.4 с исправлением отсутствует на NuGet https://github.com/dadhi/DryIoc/releases/tag/v4.2.4

...