Почему эта простая регистрация Injector приводит к пустой коллекции? - PullRequest
0 голосов
/ 28 июня 2018

У меня есть общий интерфейс, который имеет много реализаций, возможно, в разных сборках. У меня Simple Injector 4.3.0 установлен в моем проекте через NuGet, и я хочу зарегистрировать разработчиков как коллекцию. Моя конфигурация проверена Simple Injector без инцидентов, но контейнер возвращает пустую коллекцию, когда вызывается GetAllInstances.

MCVE, аналогичный моему коду:

using SimpleInjector;
using System;
using System.Linq;

namespace SIMultiInterfaceTest
{
    public interface IFoo<T> { }
    public class Bar<T> : IFoo<T> { }
    public class Baz<T> : IFoo<T> { }

    class Program
    {
        static void Main(string[] args)
        {
            var container = new Container();
            var assemblies = AppDomain.CurrentDomain.GetAssemblies();
            container.Collection.Register(typeof(IFoo<>), assemblies);
            container.Verify();
            Console.WriteLine($"{container.GetAllInstances<IFoo<int>>().Count()} in collection");
            Console.ReadLine();
        }
    }
}

Для справки, я пытаюсь реализовать сценарий регистрации, упомянутый ближе к концу этого раздела документов SI (ctrl + f: "В качестве примера представьте сценарий, в котором у вас есть тип CustomerValidator и тип GoldCustomerValidator ").

Почему регистрация простого инжектора приводит к пустой коллекции?

Мой инстинкт инстинкта заключается в том, что это может иметь какое-то отношение к Bar<T> и Baz<T>, являющимся открытыми универсальными типами - в примере показаны только закрытые типы, зарегистрированные таким образом. Я не уверен, однако, поскольку это кажется противоречащим проектным решениям, которые привели бы к этой полностью действительной строке , также с той же страницы в документах:

container.Register(typeof(IValidate<>), typeof(NullValidator<>));

1 Ответ

0 голосов
/ 28 июня 2018

Это поведение объясняется в комментариях XML для перегрузки Collection.Register(Type, Assembly[]), которую вы вызываете:

Регистрирует все конкретные неуниверсальные типы (как публичные, так и внутренние), которые определены в данном наборе assemblies и реализуют данный serviceType с образом жизни по умолчанию, и регистрируют их как коллекция serviceType. [Акцент мой]

Ваши типы, однако, являются общими. Общие типы не зарегистрированы, потому что они часто требуют особого ухода.

Чтобы зарегистрировать эти универсальные типы, есть два варианта.

Вы можете использовать Collection.Append для добавления или добавления следующих типов в коллекцию:

// Bar<T> is prepended
container.Collection.Append(typeof(IFoo<>), typeof(Bar<>));

// All non-generic registrations next
container.Collection.Register(typeof(IFoo<>), assemblies);

// Baz is appended. It will be the last element of the collection
container.Collection.Append(typeof(IFoo<>), typeof(Baz<>));

Второй вариант - использовать GetTypesToRegister для получения всех типов, в том числе универсальных:

var types = container.GetTypesToRegister(
    typeof(IFoo<>),
    assemblies,
    new TypesToRegisterOptions { IncludeGenericTypeDefinitions = true });

container.Collection.Register(typeof(IFoo<>), types);

Здесь мы вызываем GetTypesToRegister, предоставляя TypesToRegisterOptions, который указывает, что он также должен возвращать универсальные типы. Этот список типов предоставляется для перегрузки Collection.Register(Type, Type[]).

Однако обратите внимание, что в этом втором варианте порядок регистрации типов не определен и может меняться каждый раз, когда вы перекомпилируете или даже перезапускаете приложение. Если это поведение не подходит, вам придется заказать набор типов, прежде чем указывать его Collection.Register.

...