如何解析使用 DryIoc.Container 实现接口的特定类型(运行时已知)的实例

问题描述 投票:0回答:1

标题可能具有误导性,但基本上我希望

DryIoc.Container
能够解析接口的特定实现,其type(实现接口的类的类型)在runtimemultiple)处给出相同接口的实现已注册)。 我无法使用
serviceKey
来识别 implementations,因为 resolves 实现的代码预计会执行以下操作:
container.Resolve<IService>(*** here specify the runtime type of the implementation ***)
来获取我们想要的实现(实现的类型是通过我们的配置获取的)在运行时读取)。

    using System;
    using DryIoc;
    namespace DryIoc_example
    {
        interface IService { }
        class ServiceImpl_1 : IService { }
        class ServiceImpl_2 : IService { }

        class Program
        {
            static void Main(string[] args)
            {
                var container = new Container();
                // register my implementations of IService
                // this could be done at runtime using
                // container.Register(typeof(IService), typeof(ServiceImpl_1));
                container.Register<IService, ServiceImpl_1>();
                container.Register<IService, ServiceImpl_2>();

                // now, i want the container to resolve a specific
                // implementation of IService ( ServiceImpl_2 in this case)

                // this line doesn't work and throws
                var myService = container.Resolve<IService>(typeof(ServiceImpl_2));

                // this line is expected to print the type of ServiceImpl_2
                Console.WriteLine(myService.GetType());
            }
        }
    }

`

上面的代码抛出:

Unable to resolve DryIoc_example.IService {RequiredServiceType=DryIoc_example.ServiceImpl_2}

Where CurrentScope: null

  and ResolutionScope: null

  and Found registrations:

  DefaultKey.Of(0),{ID=20, ImplType=DryIoc_example.ServiceImpl_1}}

  DefaultKey.Of(1),{ID=21, ImplType=DryIoc_example.ServiceImpl_2}}

我知道我可以获得所有接口的已注册实现并过滤具有我想要的实现的实现(使用类似于此响应的代码https://stackoverflow.com/a/37069854/5767019) DryIoc 的维护者),但是当我要求容器解决它时,我无法找到一种方法来解决它!

c# ioc-container dryioc
1个回答
2
投票

DryIoc,Spring.Net 的 GetObjectsOfType 等效项?的答案几乎就在现场。

重复此处的选项:

使用实现类型作为服务密钥

container.Register<IService, ServiceImpl_1>(serviceKey: typeof(ServiceImpl_1));
container.Resolve<IService>(serviceKey: typeof(ServiceImpl_1));

使用 RegisterMany

这会将所有已实现的公共类型注册为服务类型,包括实现类型本身:

using System;
using DryIoc;
namespace DryIoc_example
{
    interface IService {}
    class ServiceImpl_1 : IService {}
    class ServiceImpl_2 : IService {}

    public class Program
    {
        public static void Main()
        {
            var container = new Container();
            
            container.RegisterMany<ServiceImpl_1>(nonPublicServiceTypes: true);
            container.RegisterMany<ServiceImpl_2>(nonPublicServiceTypes: true);
            
            var myService = container.Resolve<IService>(typeof(ServiceImpl_2));
            
            // this line is expected to print the type of ServiceImpl_2
            Console.WriteLine(myService.GetType());
        }
    }
}

实例

手动从容器注册中选择

找到给定实现类型的注册工厂,并获取用于注册的实际默认密钥。使用密钥解决:

using System;
using System.Linq;
using DryIoc;

namespace DryIoc_example
{
    public interface IService {}
    class ServiceImpl_1 : IService {}
    class ServiceImpl_2 : IService {}

    public class Program
    {
        public static void Main()
        {
                var container = new Container();

                container.Register<IService, ServiceImpl_1>();
                container.Register<IService, ServiceImpl_2>();
            
                var myService = container.TryResolveByImplementation<IService>(typeof(ServiceImpl_1));
                

                // this line is expected to print the type of ServiceImpl_1
                Console.WriteLine(myService.GetType());
        }
    }
    
    public static class ContainerExtensions
    {
        public static TService TryResolveByImplementation<TService>(this IContainer container, Type implementationType)
        {
            var factory = container.GetAllServiceFactories(typeof(TService))
                .FirstOrDefault(f => f.Value.ImplementationType == implementationType);
            
            return factory != null 
                ? container.Resolve<TService>(serviceKey: factory.Key) 
                : default(TService);
        }
    }
}

实例

© www.soinside.com 2019 - 2024. All rights reserved.