Я хотел бы передать значения в конструктор класса, реализующего мою службу.
Однако ServiceHost позволяет мне передавать только имя создаваемого типа, а не аргументы, передаваемые его конструктору.
Я хотел бы иметь возможность передать фабрику, которая создает мой объект службы.
Что я нашел на данный момент:
- WCF Dependency Injection Behavior - это больше, чем то, что я ищу, и кажется слишком сложным для моих нужд.
wcf
dependency-injection
factory-pattern
Ян Рингроуз
источник
источник
Ответы:
Вам необходимо реализовать комбинацию обычая
ServiceHostFactory
,ServiceHost
иIInstanceProvider
.Для службы с этой подписью конструктора:
Вот пример, который может развернуть MyService:
Зарегистрируйте MyServiceHostFactory в файле MyService.svc или используйте MyServiceHost непосредственно в коде для сценариев самостоятельного размещения.
Вы можете легко обобщить этот подход, и на самом деле некоторые контейнеры DI уже сделали это за вас (реплика: Windsor WCF Facility).
источник
protected
я не могу вызвать ее сам из Main ()dep
каждый контракт InstanceProvider. Вы можете сделать:ImplementedContracts.Values.First(c => c.Name == "IMyService").ContractBehaviors.Add(new MyInstanceProvider(dep));
гдеIMyService
контрактный интерфейс вашегоMyService(IDependency dep)
. Поэтому вводитеIDependency
только в InstanceProvider, который действительно в этом нуждается.Вы можете просто создать свой экземпляр
Service
и передать этот экземплярServiceHost
объекту. Единственное, что вам нужно сделать, это добавить[ServiceBehaviour]
атрибут для вашей службы и пометить все возвращаемые объекты[DataContract]
атрибутом.Вот макет:
и использование:
Надеюсь, это кому-то облегчит жизнь.
источник
InstanceContextMode.Single
).Ответ Марка
IInstanceProvider
правильный.Вместо использования настраиваемого ServiceHostFactory вы также можете использовать настраиваемый атрибут (скажем
MyInstanceProviderBehaviorAttribute
). Получите егоAttribute
, заставьте его реализоватьIServiceBehavior
и реализовать такойIServiceBehavior.ApplyDispatchBehavior
метод, какЗатем примените атрибут к классу реализации службы.
Третий вариант: вы также можете применить поведение службы с помощью файла конфигурации.
источник
Я работал с ответом Марка, но (по крайней мере, для моего сценария) это было излишне сложным. Один из
ServiceHost
конструкторов принимает экземпляр службы, который можно передать непосредственно изServiceHostFactory
реализации.Если взять пример Марка, это будет выглядеть так:
источник
instance
. Это может повлиять или не повлиять на производительность. Если вы хотите иметь возможность обрабатывать параллельные запросы, весь этот граф объектов должен быть потокобезопасным, иначе вы получите недетерминированное неправильное поведение. Если вы можете гарантировать безопасность потоков, мое решение действительно излишне сложное. Если вы не можете этого гарантировать, требуется мое решение.К черту… Я смешал шаблоны внедрения зависимостей и локатора сервисов (но в основном это все еще внедрение зависимостей, и оно даже происходит в конструкторе, что означает, что вы можете иметь состояние только для чтения).
Зависимости службы четко указаны в контракте ее вложенного
Dependencies
класса. Если вы используете контейнер IoC (тот, который еще не исправляет беспорядок WCF для вас), вы можете настроить его для созданияDependencies
экземпляра вместо службы. Таким образом вы получите теплое нечеткое ощущение, которое дает вам ваш контейнер, и при этом вам не придется перепрыгивать через слишком много препятствий, наложенных WCF.Я не собираюсь терять сон из-за такого подхода. Никто не должен. В конце концов, ваш контейнер IoC - это большая, толстая статическая коллекция делегатов, которая создает для вас вещи. Что добавляете еще?
источник
Мы столкнулись с этой же проблемой и решили ее следующим образом. Это простое решение.
В Visual Studio просто создайте обычное приложение-службу WCF и удалите его интерфейс. Оставьте файл .cs на месте (просто переименуйте его), откройте этот файл cs и замените имя интерфейса своим исходным именем класса, который реализует логику службы (таким образом, класс службы использует наследование и заменяет вашу фактическую реализацию). Добавьте конструктор по умолчанию, который вызывает конструкторы базового класса, например:
Базовый класс MyService - это фактическая реализация службы. Этот базовый класс не должен иметь конструктора без параметров, а только конструкторы с параметрами, которые принимают зависимости.
Служба должна использовать этот класс вместо исходного MyService.
Это простое решение и работает как шарм :-D
источник
Это было очень полезным решением, особенно для начинающих программистов WCF. Я действительно хотел опубликовать небольшой совет для всех пользователей, которые могут использовать это для службы, размещенной в IIS. MyServiceHost должен наследовать WebServiceHost , а не только ServiceHost.
Это создаст все необходимые привязки и т. Д. Для ваших конечных точек в IIS.
источник
Я использую статические переменные своего типа. Не уверен, что это лучший способ, но у меня он работает:
Когда я создаю экземпляр хоста службы, я делаю следующее:
источник