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

本文关键字:运行时 类型 实例 何解析 DryIoc Container 接口 实现 | 更新日期: 2023-09-27 18:02:44

标题可能是误导性的,但基本上我希望DryIoc.Container能够解决特定的实现的接口,其类型(实现接口的类的类型)是在运行时给出的(多个实现相同的接口被注册)。我不能使用serviceKey来识别实现,因为解析实现的代码预计会做这样的事情: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}}

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

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

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_2
                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);
        }
    }
}

生活例子

相关文章: