Unity не может разрешить зависимость InterfaceInterceptor

1

Я написал реализацию интерфейса интерфейса IInterceptionBehavior для выполнения некоторых протоколирования. Он имеет зависимость от ILog для ведения журнала.

public class InterceptionLoggingBehavior : IInterceptionBehavior {
  public InterceptionLoggingBehavior(ILog log) {...}
  ...
}

У меня также есть ConsoleLog который реализует ILog.

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

UnityContainer container = ...
var l = container.Resolve<com.InsightSoftware.LoggingAPI.ILog>();
var b = container.Resolve<com.InsightSoftware.Logging.InterceptionLoggingBehavior>();
var p = container.Resolve<com.InsightSoftware.MetadataAPI.ITableIdentityProvider>();

ILog (во второй строке) отлично работает, но решение InterceptionLoggingBehavior на третьей строке или ITableIdentityProvider (интерфейс, который я пытаюсь выполнить) на 4-й строке получает ошибку:

Текущий тип, com.InsightSoftware.LoggingAPI.ILog, является интерфейсом и не может быть сконструирован. Вам не хватает картографирования типов?

Мой вопрос: может ли кто-нибудь сказать мне, почему единство не может разрешить ILog если это зависимость для InterceptionLoggingBehavior?

Xml, который я использую для настройки единства, включая отображение:

<unity xmlns="http://schemas.microsoft.com/practices/2010/unity">
<sectionExtension type="Microsoft.Practices.Unity.InterceptionExtension.Configuration.InterceptionConfigurationExtension, Microsoft.Practices.Unity.Interception.Configuration" />

<alias alias="ILog"                                 type="com.InsightSoftware.LoggingAPI.ILog, com.InsightSoftware.LoggingAPI"/>
<alias alias="ConcreteLog"                          type="HubbleSandbox.ConsoleLog, HubbleSandbox" />
<alias alias="InterceptionLoggingBehavior"          type="com.InsightSoftware.Logging.InterceptionLoggingBehavior, com.InsightSoftware.Logging" />
<!--More aliases-->
<containers>
  <container>
    <extension type="Interception" />

    <!-- The type mapping that I expect to be resolved. -->
    <register type="ILog"                           mapTo="ConcreteLog" />

    <register type="ITableIdentityProvider"         mapTo="TableIdentityProvider">
      <interceptor type="InterfaceInterceptor"/>
      <interceptionBehavior type="InterceptionLoggingBehavior" />
    </register>
    <!--More registrations-->
  </container>
</containers>

(обратите внимание, что я никогда не регистрирую InterceptionLoggingBehavior, я думаю, что он неявно регистрируется, используя его в теге interceptionBehavior.)

Я также попытался настроить единство кода (не используя файл конфигурации), например:

UnityContainer container = new UnityContainer();
container.AddNewExtension<Interception>();
container.RegisterType<ILog, ConsoleLog>();
container.RegisterType<ITableIdentityProvider, TableIdentityProvider>(
    new Interceptor<InterfaceInterceptor>(),
    new InterceptionBehavior<InterceptionLoggingBehavior>());
// more registrations

var l = container.Resolve<ILog>();
var b = container.Resolve<ITableIdentityProvider>();

но я все равно получаю ту же ошибку.

Изменить/обновить. Я сделал еще несколько копаний и попытался заменить строку, где я разрешаю InterceptionLoggingBehavior с помощью

container.Resolve<InterceptionLoggingBehavior>(
  new ParameterOverride(
    "log", 
    container.Resolve<ILog>()));

и я получаю ошибку

Ошибка разрешения зависимостей, type =\"com.InsightSoftware.Logging.InterceptionLoggingBehavior \", name =\"(none) \".

Исключение произошло в то время как: Разрешение параметра \"log \" конструктора com.InsightSoftware.Logging.InterceptionLoggingBehavior (журнал com.InsightSoftware.LoggingAPI.ILog).

Исключение: InvalidCastException. Невозможно передать объект типа "HubbleSandbox.ConsoleLog" для ввода "com.InsightSoftware.LoggingAPI.ILog".

Я проверил, что типы назначаются.

public class ConsoleLog : ILog {...

а также

ILog l = new ConsoleLog();

Не вызывает никаких ошибок. Я также проверил правильность пространств имен (ILog - это общее имя интерфейса - мы используем наш ILog как фасад для ILog в log4Net - так что я проверил тройку).

С помощью

  • .Net Framework 4.5
  • Unity 2.1.505.0 (у нас возникают проблемы с последним Unity на моно)
  • Некоторые зависимости от внутренних NuGets - не уверены, что это фактор
  • 0
    Интересно. Моей первой мыслью было, что перехватчик является элементом инфраструктуры, а не одним из разрешимых сервисов. И я не уверен, что Unity применяет одинаковую логику разрешения как к вашим бизнес-классам, так и к классам инфраструктуры. Другими словами, если вы разрешаете тип явным образом, он работает. Если Unity использует его внутренне как перехватчик, вы уверены, что он разрешает его, используя тот же контейнер?
  • 0
    Хорошая мысль, но я получаю ошибку при разрешении InterceptionLoggingBehavior из того же контейнера, что и при регистрации ILog .
Показать ещё 1 комментарий
Теги:
unity-container

1 ответ

1
Лучший ответ

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

Настройка, которую я использую, включает в себя три отдельных решения:

  1. Решение API для протоколирования (очень простое)
  2. Реализация этого API, который использует перехват интерфейса интерфейса для ведения журнала (имеет зависимость от 1)
  3. Песочница, которая связывает два из них вместе и обеспечивает реализацию ILog по ILog (имеет зависимость от 1 и 2)

1 и 2 предоставляются через NuGets

Проблема заключалась в том, что я обновил имя сборки (в свойствах проекта) проекта API (от LoggingAPI до com.InsightSoftware.LoggingAPI). Затем я нажал API NuGet, а затем получил последний NuGet в проекте sandbox, однако я не помнил, чтобы получить последний NuGet в проекте реализации и повторно нажать.

В результате реализация искала класс из сборки LoggingAPI, но получала класс из сборки com.InsightSoftware.LoggingAPI, поэтому типы не совпадали, и единство не могло решить правильный тип.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню