Я знаю, это звучит глупо. Я приведу несколько фрагментов кода и постараюсь объяснить как можно больше.
Реализация № 1 - без имени
Container = new UnityContainer();
Container.RegisterType<IFirstInterface, FirstImplementation>();
Container.RegisterType<IDifferentAssemblyInterface, DifferentAssemblyImplementation>();
Container.RegisterType<ISameAssemblyInterface, SameAssemblyImplementation>();
Реализация № 2 - с именем
const string configurationName = "simpleOption";
Container = new UnityContainer();
Container.RegisterType<IFirstInterface, FirstImplementation>(configurationName);
Container.RegisterType<IDifferentAssemblyInterface, DifferentAssemblyImplementation>(configurationName);
Container.RegisterType<ISameAssemblyInterface, SameAssemblyImplementation>(configurationName);
Наблюдения
Реализация №1 работает просто отлично. Я использовал непосредственное окно, и все решается.
В реализации # 2 я использовал непосредственное окно, и все из той же сборки разрешается
Реализация # 2, непосредственное окно не может разрешить точно, IDifferentAssemblyInterface не может разрешить
Я открыл конструктор Registrations, и все зависимости
Вопросы
- Правильно ли я использую именную регистрацию?
- Передача имени так проста? Просто передайте строку при регистрации, и та же самая строка при разрешении должна работать.
- Как мне отладить / разрешить это?
Пример кода
Program.cs
static IUnityContainer Container;
static void Main(string[] args)
{
// Arrange
Container = new UnityContainer();
Container.AddExtension(new Diagnostic());
Container.RegisterType<IMessageReader, ConsoleMessageReader>("Local");
Container.RegisterType<IMessageWriter, ConsoleMessageWriter>("Local");
Container.RegisterType<Startup, Startup>("Local");
Startup startup = Container.Resolve<Startup>("Local");
// Act
startup.Run();
}
Startup.cs
public class Startup
{
IMessageReader _reader;
IMessageWriter _writer;
public Startup(IMessageReader reader, IMessageWriter writer)
{
_reader = reader;
_writer = writer;
}
public void Run()
{
_writer.WriteMessage(_reader.ReadMessage());
}
}
Message ReaderWriter
public interface IMessageReader
{
string ReadMessage();
}
public class ConsoleMessageReader : IMessageReader
{
public string ReadMessage()
{
return "Hello, DI";
}
}
public interface IMessageWriter
{
void WriteMessage(string message);
}
public class ConsoleMessageWriter : IMessageWriter
{
public void WriteMessage(string message)
{
Console.WriteLine("{0}", message);
}
}
Сообщение об ошибке
Unhandled Exception: Unity.ResolutionFailedException: The current type, HelloDIApp.ConsoleClient.IMessageReader, is an interface and cannot be constructed. Are you missing a type mapping?
_____________________________________________________
Exception occurred while:
·resolving type: 'IMessageReader'
for parameter: 'reader'
on constructor: Startup(IMessageReader reader, IMessageWriter writer)
resolving type: 'Startup' registered with name: 'Local'
---> System.InvalidOperationException: The current type, HelloDIApp.ConsoleClient.IMessageReader, is an interface and cannot be constructed. Are you missing a type mapping? ---> Unity.Exceptions.InvalidRegistrationException: Exception of type 'Unity.Exceptions.InvalidRegistrationException' was thrown.
--- End of inner exception stack trace ---
at Unity.Processors.ConstructorDiagnostic.<>c.<GetResolver>b__11_0(BuilderContext& c)
at Unity.Processors.MemberProcessor`2.<>c__DisplayClass8_0.<GetResolver>b__0(BuilderContext& c)
at Unity.Processors.MemberProcessor`2.<>c__DisplayClass8_0.<GetResolver>b__0(BuilderContext& c)
at Unity.Processors.MemberProcessor`2.<>c__DisplayClass8_0.<GetResolver>b__0(BuilderContext& c)
at Unity.UnityContainer.<>c__DisplayClass96_0.<OptimizingFactory>b__0(BuilderContext& c)
at Unity.Strategies.BuildPlanStrategy.PreBuildUp(BuilderContext& context)
at Unity.UnityContainer.ContextValidatingPlan(BuilderStrategy[] chain, BuilderContext& context)
at Unity.Builder.BuilderContext.Resolve(Type type, String name, InternalRegistration registration)
at Unity.Builder.BuilderContext.Resolve(Type type, String name)
at Unity.Builder.BuilderContext.Resolve(ParameterInfo parameter, Object value)
at Unity.Processors.ParametersProcessor`1.<>c__DisplayClass1_0.<CreateDiagnosticParameterResolvers>b__0(BuilderContext& context)
at Unity.Processors.ConstructorDiagnostic.<>c__DisplayClass12_0.<GetResolverDelegate>b__0(BuilderContext& c)
at Unity.Processors.MemberProcessor`2.<>c__DisplayClass8_0.<GetResolver>b__0(BuilderContext& c)
at Unity.Processors.MemberProcessor`2.<>c__DisplayClass8_0.<GetResolver>b__0(BuilderContext& c)
at Unity.Processors.MemberProcessor`2.<>c__DisplayClass8_0.<GetResolver>b__0(BuilderContext& c)
at Unity.UnityContainer.<>c__DisplayClass96_0.<OptimizingFactory>b__0(BuilderContext& c)
at Unity.Strategies.BuildPlanStrategy.PreBuildUp(BuilderContext& context)
at Unity.UnityContainer.ExecuteValidatingPlan(BuilderContext& context)
--- End of inner exception stack trace ---
at Unity.UnityContainer.ExecuteValidatingPlan(BuilderContext& context)
at Unity.UnityContainer.Unity.IUnityContainer.Resolve(Type type, String name, ResolverOverride[] overrides)
at Unity.UnityContainerExtensions.Resolve[T](IUnityContainer container, String name, ResolverOverride[] overrides)
at HelloDIApp.ConsoleClient.Program.Main(String[] args) in C:\Code\HelloDI\HelloDIApp\HelloDIApp.ConsoleClient\Program.cs:line 18
Рабочий код
Когда я не использую имена, это прекрасно работает.
static void Main(string[] args)
{
// Arrange
Container = new UnityContainer();
Container.AddExtension(new Diagnostic());
Container.RegisterType<IMessageReader, ConsoleMessageReader>();
Container.RegisterType<IMessageWriter, ConsoleMessageWriter>();
Container.RegisterType<Startup, Startup>();
Startup startup = Container.Resolve<Startup>();
// Act
startup.Run();
}