2

标题可能具有误导性,但基本上我想DryIoc.Container解析一个接口的特定实现,其类型(实现接口的类的类型)在运行时给出(注册了同一接口的多个实现)。我不能用来识别实现,因为解析实现的代码预计会执行以下操作:获取我们想要的实现(实现的类型是通过我们在运行时读取的配置获取的)。serviceKeycontainer.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的代码),但是当我要求它时,我想不出一种方法让容器解决它!

4

1 回答 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_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);
        }
    }
}

活生生的例子

于 2016-08-17T07:37:21.330 回答