Search code examples
dryioc

Creating a fallback container/resolver DryIoc


Current working on creating a Prism.DryIoc.Forms project to try out DryIoc (first time!).

In Xamarin.Forms there is a native DependencyService and to provide a nice way to migrate towards using Prism I would like to add it as a fallback container in case the requsted service type can't be resolved from the main container.

Current I have created a FallbackContainer and pass the instance of IContainerand overrides the methods for IResolver and delegates the rest of the IContainer calls to the instance passed during creation.

So after the default container is created and configured and then do

Container = CreateContainer();
ConfigureContainer();
Container.Rules.WithFallbackContainer(new DependencyServiceContainer(Container));

Is this the preferred method or is there any way just to attach a default IResolver?

Current implementation

public class FallbackDependencyServiceContainer : IContainer
    {
        private readonly IContainer container;

        public FallbackDependencyServiceContainer(IContainer container)
        {
            this.container = container;
        }

        public object Resolve(Type serviceType, bool ifUnresolvedReturnDefault)
        {
            return ResolveFromDependencyService(serviceType);
        }

        public object Resolve(Type serviceType, object serviceKey, bool ifUnresolvedReturnDefault,
            Type requiredServiceType,
            RequestInfo preResolveParent, IScope scope)
        {
            return ResolveFromDependencyService(serviceType);
        }

        public IEnumerable<object> ResolveMany(Type serviceType, object serviceKey, Type requiredServiceType,
            object compositeParentKey,
            Type compositeParentRequiredType, RequestInfo preResolveParent, IScope scope)
        {
            return new[] { ResolveFromDependencyService(serviceType) };
        }

        private static object ResolveFromDependencyService(Type targetType)
        {
            if (!targetType.GetTypeInfo().IsInterface)
            {
                return null;
            }
            var method = typeof(DependencyService).GetTypeInfo().GetDeclaredMethod("Get");
            var genericMethod = method.MakeGenericMethod(targetType);
            return genericMethod.Invoke(null, new object[] { DependencyFetchTarget.GlobalInstance });
        }
....
}

Thanks and looking forward to test DryIoc since I've read it's supposed to be the fastest out there


Solution

  • Updated answer:

    You may directly use WithUnknownServiceResolvers returning DelegateFactory:

    var c = new Container(Rules.Default.WithUnknownServiceResolvers(request =>
        new DelegateFactory(_ => GetFromDependencyService(request.ServiceType))));
    

    No need to implement IContainer just for that.

    I think it may be optimized regarding performance by replacing DelegateFactory with ExpressionFactory. But I need some time to play with the idea.