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

Spring.Net の GetObjectsOfType に相当する DryIoc の答えは? ほぼその場にあります。

ここでオプションを繰り返します:

実装タイプをサービス キーとして使用する

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 に答える