2016-04-11 10 views
5

У меня возникли трудности с использованием StructureMap для сервисов, где в конструкторе есть аргумент с нулевым значением. То естьStructureMap, передающий null в конструкторе

public JustGivingService(IRestClient restClient = null) 

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

container.For<IJustGivingService>().Use<JustGivingService>() 

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

RestClient restClient = null; 
container.For<IJustGivingService>().Use<JustGivingService>() 
    .Ctor<IRestClient>("restClient").Is(restClient); 

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

+2

небольшая альтернатива 'container.For () Использование () CTOR ("restClient") Is (() => NULL); 'Получает освобождение от переменной как минимум – Thymine

+0

@Thymine Большое вам спасибо! Это то, что, наконец, работало через 4 часа, ударяя головой о стол, о том, почему StructureMap не хочет разрешать мой экземпляр с нулевым параметром в моем конструкторе. – silkfire

+0

@Thymine ты так много !! – RPM1984

ответ

5

StructureMap не поддерживает необязательные параметры конструктора, и это не должно. Как описано в this blog post:

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

Таким образом, решение заключается в создании Null Object реализации для IRestClient и зарегистрировать, что внедрение в StructureMap.

Пример:...

// Null Object pattern 
public sealed class EmptyRestClient : IRestClient { 
    // Implement IRestClient methods to do nothing. 
} 

// Register in StructureMap 
container.For<IRestClient>().Use(new EmptyRestClient()); 
+0

Интересно, поэтому я должен, например, удалить '= null' и создать конструктор без параметров? В каком случае, как установить значение по умолчанию для параметра без параметров? – ediblecode

+2

@jumpingcode, нет, вы не должны создавать конструктор по умолчанию. Каждый компонент должен иметь [ровно один конструктор] (https://www.cuttingedge.it/blogs/steven/pivot/entry.php?id=97), который задает все зависимости класса. Поэтому ваш компонент JustGivingService должен иметь конструктор: 'JustGivingService (IRestClient restClient)' (обратите внимание: без '= null'), и вы также должны зарегистрировать свою пустую реализацию IRestClient в StructureMap. – Steven