Свободная архитектура поиска сервисов с расширением Ninject WCF - PullRequest
1 голос
/ 21 апреля 2011

Я наконец понял, как Ninject обрабатывает DI, но столкнулся со следующей проблемой:

Давайте рассмотрим класс, который принимает два объекта WCF ServiceHost в качестве параметров конструктора:

public ActivitySinkServer(IDataProvider dataProvider, ServiceHost posClients, ServiceHost activitySinkOperatorClients)

Сначала у меня была только одна зависимость ServiceHost, поэтому я легко обработал привязку следующим образом:

public class CommunicationModule: NinjectModule
{
public override void Load()
        {
            Bind<POSClient>().ToSelf().WithConstructorArgument("posManager", Kernel.Get<POSManager>());

            this.Bind<ServiceHost>().ToMethod(ctx => ctx.Kernel.Get<NinjectServiceHost>(new ConstructorArgument("singletonInstance", c => c.Kernel.Get<POSClient>())));
        }
}

В этом сценарии мой ActivitySinkServer может разрешить зависимость ServiceHost с NinjectServiceHost, инициализированным одноэлементным объектом.

Теперь, когда у меня есть две зависимости ServiceHost, как я могу сказать Ninject, какую из них передать для какого параметра конструктора, при этом мой внутренний код остается незаметным для Ninject. (Я знаю, что мог использовать атрибуты Ninject и другие материалы из руководства).

UPDATE:

Я пошел вперед и просто использовал

.When(request => request.Target.Name == "posClients");
.When(request => request.Target.Name == "activitySinkOperatorClients");

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

1 Ответ

0 голосов
/ 15 августа 2011

То, как вы это делаете, прекрасно на 100%;более «изящный» способ сделать это - использовать именованные привязки или метаданные.

Кстати, гораздо лучше не использовать в этом конструкторе singletonInstance ServiceHostслучай, потому что если вы инициализируете его таким образом, то WCF не позволит вам использовать любой другой режим создания экземпляров (например, PerCall).Пусть Ninject и WCF обрабатывают создание экземпляров и используют вместо этого конструктор на основе типов.

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

class ServiceModule : NinjectModule
{
    public override void Load()
    {
        Bind<ServiceHost>().To<NinjectServiceHost>().Named("POS")
            .WithConstructorArgument("serviceType", typeof(PosService))
            .WithConstructorArgument("baseAddresses", new Uri[0]);

        Bind<ServiceHost>().To<NinjectServiceHost>().Named("ActivitySink")
            .WithConstructorArgument("serviceType", typeof(ActivitySink))
            .WithConstructorArgument("baseAddresses", new Uri[0]);
    }
}

public class Server
{
    private readonly ServiceHost posHost;
    private readonly ServiceHost activitySink;

    public Server(IDataProvider dataProvider,
        [Named("POS")] posHost,
        [Named("ActivitySink")] activitySink)
    {
        this.posHost = posHost;
        this.activitySink = activitySink;
    }
}

Обратите внимание, что инициализация аргумента конструктора baseAddresses необходима дляNinject, чтобы выбрать правильную перегрузку.Инициализация его new Uri[0], в частности, просто вызывает поведение по умолчанию при поиске в app.config для поиска базовых адресов, поэтому не беспокойтесь о передаче пустого массива.

Хотя это объединяет ваш Server классЧтобы внедрить себя, обычно ваши ServiceHost экземпляры создаются в двоичном файле приложения, а не в библиотеке, поэтому связь не является проблемой.

Я предпочитаю этот подход синтаксису When, поскольку он менее вероятенсломаться во время рефакторинга.Не исключено, что однажды кто-нибудь решит изменить имена параметров конструктора, и нет никаких визуальных указаний на то, что что-то зависит от этих имен, и нет никакого способа для автоматического рефакторинга Visual Studio обнаружить эту зависимость.

Итак, IMO, лучше сделать зависимость явной здесь, используя атрибуты;таким образом, если кто-то решит добавить третий сервисный хост позже, он сразу узнает, что ему нужно добавить атрибут и обновить соответствующий модуль Ninject.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...