Заставить WCF OperationContext хорошо играть с DI и тестированием - PullRequest
4 голосов
/ 13 июля 2011

Я использую службу WCF, размещенную в службе Windows;зависимости службы WCF внедряются через Unity, и это хорошо.В результате сервис также легко написать модульные тесты для.

Недавно я добавил функциональность в сервис, который использует OperationContext для проверки входящих сообщений.К сожалению, это скорее вырывает тестируемость сервиса из-за привязанности Microsoft к закрытым и / или статическим классам и отсутствию интерфейсов и / или виртуальных методов.

Поэтому я обратился к .NET'ersЛюбимый инструмент в этой ситуации, класс-обертка.Поскольку это общая проблема, чей-то уже проделал тяжелую работу для нас .Так что это добавляет новую зависимость к моей службе WCF, реализацию IOperationContext.Это не было проблемой для моих модульных тестов, NSubstitute - мой выбор фреймворка (например, Moq, но без проклятия .Object).

Однако, когда я пытаюсь запустить сервис по-настоящему,У меня следующая проблема - упаковываемый OperationContext не был инициализирован во время регистрации контейнера IoC.Мой код инициализации (здесь используется Unity):

container.RegisterType<IOperationContext, OperationContextWrapper>(new InjectionConstructor(OperationContext.Current));

, но на данный момент OperationContext.Current равен null, поэтому Unity быстро выдает исключение, и мои мечты об уходе на пенсию до 40 лет превращаются в дым..

Итак, вопрос в том, как заставить WCF хорошо играть с DI и завернутым OperationContext?

.

Ответы [ 3 ]

2 голосов
/ 13 июля 2011

Может быть, я не понимаю, но я не уверен, почему вы хотите добавить OperationContext.Current в вашу оболочку.Если OperationContextWrapper оборачивает OperationContext, то почему бы просто не реализовать его реализацию напрямую с OperationContext.Current, где это необходимо?Я предполагаю, что код, который вы пытаетесь сохранить тестируемым, это не OperationContextWrapper, а код, который зависит от него через интерфейс IOperationContext?Тогда кого это волнует, что делает OperationContextWrapper?

1 голос
/ 21 февраля 2014

Вы также можете использовать Microsoft Fakes:

using (ShimsContext.Create()) 
{
ShimOperationContext shimOperationContext = new
ShimOperationContext(); shimOperationContext.SessionIdGet = () => "sessionId";

OperationContext.Current = shimOperationContext;
}
1 голос
/ 13 июля 2011

OperationContext.Current является настраиваемым свойством.Можете ли вы изменить инициализацию теста на

OperationContext.Current = new OperationContextWrapper();

и заставить это работать таким образом?Если вам это нужно в единстве, вы также можете:

var oc = new OperationContextWrapper();
OperationContext.Current = oc;
container.RegisterInstance<IOperationContext>(oc);
...