The code below worked in DryIoc 2.x. I just updated to 4.x. The code no longer works (see the exception below). It appears that 4.x treats the "ScopedTo" data as non-exclusive, whereas in 2.x they were exclusive to the scope -- they weren't available to other scopes out of the box. How do I get the 2.x behavior now? The exception lists several remedies, but which remedy matches the 2.x behavior?
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>();
}
}
}
The exception that I get in 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 ```
Seems like a bug. I have created the respective issue in DryIoc repository https://github.com/dadhi/DryIoc/issues/290. Please move the discussion there.
The issue will appear only with Reuse.Singleton
parent services. So until the issue is fixed, the workaround may be to change Owner
reuse or to insert artificial scope to play the role of a singleton for those services.
DryIoc v4.2.4 with the fix is out on NuGet https://github.com/dadhi/DryIoc/releases/tag/v4.2.4