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
下面的代码适用于 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