使用名称的Unity容器注册不起作用,而没有名称工作正常

问题描述 投票:0回答:1

我知道这听起来很愚蠢。我将提供一些代码,并将尽力解释。

Implementation #1 - Without name

   Container = new UnityContainer();

    Container.RegisterType<IFirstInterface, FirstImplementation>();

    Container.RegisterType<IDifferentAssemblyInterface, DifferentAssemblyImplementation>();
    Container.RegisterType<ISameAssemblyInterface, SameAssemblyImplementation>();

Implementation #2 - With name

const string configurationName = "simpleOption";

Container = new UnityContainer();

        Container.RegisterType<IFirstInterface, FirstImplementation>(configurationName);

        Container.RegisterType<IDifferentAssemblyInterface, DifferentAssemblyImplementation>(configurationName);
        Container.RegisterType<ISameAssemblyInterface, SameAssemblyImplementation>(configurationName);

Observations

实现#1工作得很好。我使用了即时窗口,一切都解决了。

通过实现#2,我使用了即时窗口,来自同一程序集的所有内容都可以解析

实现#2立即窗口无法准确解析IDifferentAssemblyInterface无法解析

我打开了Registrations构造函数,所有的依赖项都是

Questions

  1. 我正确使用命名注册吗?
  2. 传递名字就这么简单吗?只需在注册时传递一个字符串,并且在解析期间应该使用相同的字符串。
  3. 我该如何调试/解决此问题?

Sample Code

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());
        }
    }

消息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);
    }
}

Error 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

Working Code

当我不使用名字时它工作得很好。

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();
}
c# dependency-injection dependencies containers unity-container
1个回答
0
投票

找到了一种方法。我还在寻找答案。

在构建复杂对象时,我们可以告诉团结我们如何选择依赖关系。我们可以使用不同名称的所有组合并创建依赖关系图。在解析后,Unity将根据该名称下的订单进行完全构建。

static void Main(string[] args)
{
    // Arrange
    Container = new UnityContainer();
    Container.AddExtension(new Diagnostic());


    Container.RegisterType<IMessageReader, ConsoleMessageReader>();
    Container.RegisterType<IMessageWriter, ConsoleMessageWriter>();

    Container.RegisterType<IMessageReader, TwitterMessageReader>("Social");
    Container.RegisterType<IMessageWriter, FacebookMessageWriter>("Social");
    Container.RegisterType<IStartup, Startup>("Social", new InjectionConstructor(new ResolvedParameter<IMessageReader>("Social"), new ResolvedParameter<IMessageWriter>("Social")));

    Container.RegisterType<IMessageReader, ConsoleMessageReader>("Local");
    Container.RegisterType<IMessageWriter, ConsoleMessageWriter>("Local");

    var reader = Container.Resolve<IMessageReader>("Social");
    var writer = Container.Resolve<IMessageWriter>();

    Container.RegisterType<IStartup, Startup>("Local", new InjectionConstructor(reader, writer));

    IStartup startup = Container.Resolve<IStartup>("Local");

    // Act
    startup.Run();
}
© www.soinside.com 2019 - 2024. All rights reserved.