Реализуйте Ленивый Прокси в Простом Инжекторе - PullRequest
1 голос
/ 15 марта 2019

Документы Simple Injector описывают , как реализовать ленивую зависимость. Однако этот пример охватывает только регистрацию простого интерфейса (IMyService). Как это будет работать с открытым универсальным (EG. IMyService<T>)?

Вот моя существующая регистрация:

container.Register(typeof(IDbRepository<>), typeof(DbRepository<>));

Очевидно, что следующий код не компилируется, так как я не указываю универсальный тип:

container.Register(typeof(IDbRepository<>),
    () => new LazyDbRepositoryProxy<>(new Lazy<IDbRepository<>(container.GetInstance<>)));

Возможно ли это в простом инжекторе? Я вижу только следующие переопределения для Register, не позволяющие передавать func / instanceCreator в:

public void Register(Type openGenericServiceType, params Assembly[] assemblies);
public void Register(Type openGenericServiceType, IEnumerable<Assembly> assemblies);
public void Register(Type openGenericServiceType, Assembly assembly, Lifestyle lifestyle);
public void Register(Type openGenericServiceType, IEnumerable<Assembly> assemblies, Lifestyle);
public void Register(Type openGenericServiceType, IEnumerable<Type> implementationTypes, Lifestyle);
public void Register(Type openGenericServiceType, IEnumerable<Type> implementationTypes);

1 Ответ

1 голос
/ 15 марта 2019

Кодовая конструкция, которую вы предложили, не та, которую вы можете выразить в C #.Но, внеся небольшие изменения в свой дизайн, вы сможете элегантно решить вашу проблему.

Хитрость заключается в том, чтобы ввести Container в LazyDbRepositoryProxy<T>.Таким образом, Simple Injector может легко создавать новые LazyDbRepositoryProxy<T> экземпляры, используя автоматическую разводку, что предотвращает необходимость регистрации делегата (что не работает для типов с открытым универсальным типом).

Так что измените свой LazyDbRepositoryProxy<T> к следующему:

// As this type depends on your DI library, you should place this type inside your
// Composition Root.
public class LazyDbRepositoryProxy<T> : IDbRepository<T>
{
    private readonly Lazy<DbRepository<T>> wrapped;

    public LazyDbRepositoryProxy(Container container)
    {
        this.wrapped = new Lazy<IMyService>(container.GetInstance<DbRepository<T>>));
    }
}

И зарегистрируйте свои типы следующим образом:

container.Register(typeof(DbRepository<>));
container.Register(typeof(IDbRepository<>), typeof(LazyDbRepositoryProxy<>));
...