Внедрение контекста и параметров в граф зависимостей Ninject 2 - PullRequest
2 голосов
/ 11 июля 2011

Я заинтересован в создании экземпляра объекта, который реализует мой IDistributor интерфейс с использованием IoC и Ninject.

Я создал конкретную реализацию (Distributor) и все зависимые объекты / интерфейсы, как требуется.

Для Distributor требуется инжектированная конструктором зависимость типа IDistributorContext. Конкретный тип DistributorContext может быть создан только путем передачи параметров во время выполнения.

Я изо всех сил пытаюсь выбрать лучший способ реализации этого, а также лучший способ инкапсулировать это для ознакомления с остальной частью моего приложения. В настоящее время я решил создать Factory, которая отвечает за создание ядра Ninject и разрешение зависимостей в методе Create. Итак, мои вопросы:

  1. Является ли это предпочтительным решением? Или было бы лучше создать Модуль, который затем будет доступен для других моих сборок и позволит им создать экземпляр объекта?
  2. Каков предпочтительный способ создания Distributor во время выполнения? Отметив параметры времени выполнения, которые необходимо предоставить объекту DistributorContext, вниз по графику зависимостей.

Код:

public class DistributorFactory : IDistributorFactory
{
    private const string ContextIdKey = "contextIdKey";
    private readonly IKernel _kernel;

    public DistributorFactory()
    {
        _kernel = CreateKernel();
    }

    public IDistributor Create(int queueId)
    {
        return _kernel.Get<IDistributor>(new Parameter(ContextIdKey, queueId, true));
    }

    private IKernel CreateKernel()
    {
        var kernel = new StandardKernel();

        kernel.Bind<IDistributorContext>().To<DistributorContext>().WithConstructorArgument("contextId",
            (context, target) => context.Parameters.First(x => x.Name == QueueIdKey).GetValue(context, target));

        kernel.Bind<IReceiveQueue>().To<ReceiveQueue>();
        kernel.Bind<IDistributor>().To<Distributor>();

        return kernel;
    }
}

public class Distributor : IDistributor
{
    private readonly IReceiveQueue _receiveQueue;
    private readonly IDistributorContext _distributorContext;

    public Distributor(IReceiveQueue receiveQueue, IDistributorContext distributorContext)
    {
        _receiveQueue = receiveQueue;
        _distributorContext = distributorContext;
    }
}

public class DistributorContext: IDistributorContext
{
    private readonly int _contextId;

    public DistributorContext(int contextId)
    {
        _contextId = contextId;
    }
}

Edit:

Мое приложение создает несколько распространителей на основе параметров конфигурации, хранящихся в XML. Я не хочу связывать свою конфигурацию на основе сервисов с моей реализацией дистрибьютора, и поэтому я пошел по пути создания фабрики.

Альтернативой может быть создание IDistributorConfiguration и получение Ninject для автоматического предоставления списка Distributors моей потребляющей службе. Но опять же, я не уверен, что это лучше?

1 Ответ

1 голос
/ 11 июля 2011

работает?Да, безусловно.

Является ли это предпочтительным решением?Возможно нет.Это сложное решение, которое обычно указывает на то, что в реализации что-то не так.Но чтобы ответить на этот вопрос, вы должны предоставить информацию, какова цель вашей реализации.И под целью я имею в виду не то, что вы хотите сделать от Ninject, а то, что должно делать ваше приложение.

...