В чем разница между этими двумя конфигами StructureMap? - PullRequest
2 голосов
/ 09 декабря 2011

Мы пытаемся понять разницу между этими двумя способами настройки StructureMap. Мы понимаем, что они должны быть идентичными, но мы получаем разные результаты между этими двумя строками внутри Initialize:

ObjectFactory.Initialize(x =>
{
    x.For<IBusinessRelationsContext>().Use<BusinessRelationsContext>().Ctor<string>().Is(ConfigurationManager.ConnectionStrings["BusinessRelationsContext"].ConnectionString);
    x.For<IBusinessRelationsContext>().Use(_ => new BusinessRelationsContext(ConfigurationManager.ConnectionStrings["BusinessRelationsContext"].ConnectionString));
});

(мы используем только 1 из двух одновременно - очевидно, не оба)

Наши различные подписи конструктора на этом объекте (это EF4, если вам интересно):

public BusinessRelationsContext();
public BusinessRelationsContext(string connectionString);
public BusinessRelationsContext(EntityConnection connection);

Код, который мы используем для вызова этого:

ObjectFactory.TryGetInstance<IBusinessRelationsContext>();

Различие в поведении, которое мы видим, состоит в том, что строка, включающая Ctor<string>, терпит неудачу, потому что StructureMap дает сбой с 202 «Нет экземпляра по умолчанию, определенного для PluginFamily System.Data.Common.DbConnection» (мы понятия не имеем, почему он так считает нужно это). Однако, если я прокомментирую эту строку и использую другую, она работает отлично, как и следовало ожидать. Учитывая, что другой работает, я подозреваю, что мое понимание того, что для него не требуется конфигурация для DbConnection, является правильным.

Поэтому, вместо того, чтобы отследить, ПОЧЕМУ ему требуется соединение DbConnection, я бы предпочел отследить ответ на мой вопрос: в чем разница между этими двумя?

Ответы [ 2 ]

3 голосов
/ 09 декабря 2011

Я думаю, что StructureMap выбирает самый сложный конструктор, чтобы попытаться создать ваш текст данных. То, что вы определили с помощью вызова Ctor, - это определение того, как определить этот класс с использованием менее сложного конструктора.

То есть ваше определение не является неправильным, просто StructureMap не вызывает конструктор, который, как вы думаете, должен вызывать.

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

x.For<IBusinessRelationsContext>().Use(_ => new BusinessRelationsContext(ConfigurationManager.ConnectionStrings["BusinessRelationsContext"].ConnectionString));
0 голосов
/ 09 декабря 2011

Таким образом, у меня был кто-то в автономном режиме, помогавший мне с этим (не думал, что у меня есть какие-либо автономные ресурсы по этому вопросу!), И проблема в том, как объяснил Халид Абухакмех - он выбирает самый сложный (самый «жадный» - *) 1001 * подробнее здесь ).

Теперь, когда мы знаем проблему, мы можем искать решение. В моем случае (и в случае тех, кто комментирует здесь), решение состоит в том, чтобы добавить такую ​​строку:

x.SelectConstructor<IBusinessRelationsContext>(() => new BusinessRelationsContext(""));
...