Я написал реализацию интерфейса интерфейса 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
- так что я проверил тройку).
С помощью
Я нашел ответ на свой вопрос после немного больше копания, поэтому я опубликую его на случай, если кто-то еще обнаружит, что у них есть одна и та же проблема.
Настройка, которую я использую, включает в себя три отдельных решения:
ILog
по ILog
(имеет зависимость от 1 и 2)1 и 2 предоставляются через NuGets
Проблема заключалась в том, что я обновил имя сборки (в свойствах проекта) проекта API (от LoggingAPI
до com.InsightSoftware.LoggingAPI
). Затем я нажал API NuGet, а затем получил последний NuGet в проекте sandbox, однако я не помнил, чтобы получить последний NuGet в проекте реализации и повторно нажать.
В результате реализация искала класс из сборки LoggingAPI
, но получала класс из сборки com.InsightSoftware.LoggingAPI
, поэтому типы не совпадали, и единство не могло решить правильный тип.
InterceptionLoggingBehavior
из того же контейнера, что и при регистрацииILog
.