Может ли какой-либо из существующих контейнеров IoC динамически создавать ленивые прокси-классы? - PullRequest
3 голосов
/ 18 марта 2012

Я изучаю различные модели DI.А теперь меня интересует ленивая пожизненная реализация.Например, я хочу написать прокси-класс, который скрывает фабрику за интерфейсом сервиса.Может ли какой-либо из существующих контейнеров IoC (.NET) динамически создавать прокси-класс такого типа во время выполнения?

interface IService
{
    void Foo();
    void Bar();
}

class ServiceFactoryProxy : IService
{
    private readonly Func<IService> _factory;

    public ServiceFactoryProxy(Func<IService> factory)
    {
        if (factory == null) throw new ArgumentNullException("factory");
        _factory = factory;
    }

    public void Foo()
    {
        _factory().Foo();
    }

    public void Bar()
    {
        _factory().Foo();
    }
}

Ответы [ 2 ]

1 голос
/ 18 марта 2012

Unity делает это из коробки. Вы объявляете зависимость типа Func<IService> в своем конструкторе (как вы сделали с ServiceFactoryProxy) и сообщаете Unity, как она должна разрешать IService. Контейнер сгенерирует для вас делегата.


Обновление

Этот прокси выглядит как инкапсуляция Lazy<T>.

Если это ваше намерение, вы можете посмотреть это расширение для Unity .

Насколько я знаю, в Unity 3.0 будет поддержка .NET4, поэтому я ожидаю, что нечто подобное появится в составе Unity в следующем выпуске.


Update2

Это заняло у меня некоторое время, но я закончил ленивую функцию прокси. Он генерирует код IL, который выглядит следующим образом

public class MyContract_LazyInstantiationProxy : IMyContract
{
  private readonly Lazy<IMyContract> instance;
  public MyContract_LazyInstantiationProxy(Func<IMyContract> factory)
  {
    Guard.AssertNotNull(factory, "factory");
    this.instance = new Lazy<IMyContract>(factory);
  }
  public IMyContract Instance
  {
    get { return this.instance.Value; }
  }
  public string Foo(Bar bar)
  {
    return this.Instance.Foo(bar);
  }
}

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

Посмотрите на проект TecX на codeplex . Генерацию отложенного прокси можно найти в исходном коде TecX.Unity.Proxies . Пример его использования приведен в соответствующем тестовом проекте TecX.Unity.Proxies.Test .

1 голос
/ 18 марта 2012

Вот как это можно сделать в замке:

http://litemedia.info/lazy-loading-property-with-castle-dynamicproxy2

...