Unity не может правильно разрешить реализацию InstanceContext WCF
Я пытаюсь настроить клиент для дуплексной службы WCF через Unity 2.0. Для этого я хочу вставить реализацию моего CallbackContract - IUpdateClient
- в InstanceContext
, который затем вставляется в мой прокси-сервер службы, в этом случае подкласс DuplexClientBase<IUpdateService>
называется UpdateProxy
,
Проблема, с которой я сталкиваюсь, заключается в том, что при попытке использовать прокси-сервер, хранящийся в моем контейнере Unity, для подписки клиента на обновления из службы, я получаю следующее исключение:
InstanceContext, предоставленный ChannelFactory, содержит UserObject, который не реализует CallbackContractType '..Services..ServiceContracts.IUpdateClient'.
Я получаю доступ к прокси-серверу примерно так:
_container.Resolve<IUpdateService>("updateServiceImpl").Subscribe();
Учитывая мой конфиг Unity:
<!-- Interface to implementation mappings -->
<register type="RepositoryInterface" mapTo="Repository" name="repositoryImpl">
<constructor>
<param name="proxy" dependencyName="proxyImpl"/>
</constructor>
</register>
<!-- Here's the bit that doesn't seem to be resolving as expected -->
<register type="UpdateClientInterface" mapTo="UpdateClient" name="updateClientImpl">
<lifetime type="singleton"/>
<constructor>
<param name="repository" dependencyName="repositoryImpl"/>
</constructor>
</register>
<register type="System.ServiceModel.InstanceContext, System.ServiceModel,
Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" name="instanceContext">
<constructor>
<param name="implementation" dependencyName="updateClientImpl"/>
</constructor>
</register>
<!-- This is the type I'm resolving with the above _container.Resolve() statement -->
<register type="UpdateServiceInterface" mapTo="UpdateService" name="updateServiceImpl">
<constructor>
<param name="callbackInstance" dependencyName="instanceContext"/>
</constructor>
</register>
<register type="ProxyInterface" mapTo="Proxy" name="proxyImpl">
<constructor>
<param name="configurationName">
<value value="ServiceEndpointFromAppConfig"/>
</param>
</constructor>
</register>
Я ожидаю, что когда я решу класс UpdateService, можно увидеть здесь:
public class UpdateProxy : DuplexClientBase<IUpdateService>, IUpdateService
{
public UpdateProxy(InstanceContext callbackInstance)
: base(callbackInstance) {}
public void Subscribe() {}
[...]
}
Что контейнер Unity создает экземпляр InstanceContext
(зарегистрированный как "instanceContext" в конфигурации) и, при этом, он должен создавать экземпляр типа, зарегистрированного как "updateClientImpl" - который, фактически, реализуетIUpdateClient
- и передать это в конструктор InstanceContext как его implementation
параметр.
Тем не менее, я получаю ошибку, как указано выше.
Подведем итоги (он же "версия tl;dr"): когда контейнер Unity разрешает InstanceContext, он, похоже, не создает свою реализацию правильно. Я не знаю, является ли это ошибкой в конфигурации, или я в корне неправильно понимаю, как контейнер Unity разрешает набор зависимых типов. Любое руководство по этому вопросу будет полезно.
1 ответ
Проблема, с которой вы сталкиваетесь, заключается в том, что вы зарегистрировали InstanceContext с именем. Однако тип UpdateProxy вообще не зарегистрирован. Таким образом, происходит то, что контейнер будет пытаться разрешить InstanceContext, используя безымянную регистрацию по умолчанию.
Тем не менее, поскольку регистрация по умолчанию отсутствует, используются значения по умолчанию, и похоже, что он выбирает другой конструктор.
Исправление будет состоять в том, чтобы либо зарегистрировать UpdateProxy и настроить эту регистрацию на использование именованной регистрации для InstanceContext, либо удалить имя из регистрации для InstanceContext.