【问题标题】:ResolveAll not working解决所有不工作
【发布时间】:2015-01-26 17:47:34
【问题描述】:

我有一个看起来像这样的代码。在尝试执行ResolveAll 时,我希望使用IParserType 注册的每种类型都会从容器实例中产生。但我没有从Unity 得到任何实例。我在这里假设或做错了什么。

public class ResolveAllDemo
{
    public ResolveAllDemo()
    {
        var container = new UnityContainer();

        container.RegisterInstance<IUnityContainer>(container);
        container.RegisterType<IParser, SuperParser>();
        container.RegisterType<IParser, DefaultParser>();
        container.RegisterType<IParser, BasicParser>();
        //   container.RegisterType<Crawler>();
        container.RegisterType<IParserFactory, UnityParserFactory>();

        foreach (var registeredMember in container.ResolveAll<IParser>())
        {
            LoggingUtility.LogerInstance.Logger.Write(registeredMember);
        }
    }

    #region Resolve Demo

    public interface IParserFactory
    {
        IEnumerable<IParser> BuildParsers();
    }

    public class UnityParserFactory : IParserFactory
    {
        private IUnityContainer _container;

        public UnityParserFactory(IUnityContainer container)
        {
            _container = container;
        }

        public IEnumerable<IParser> BuildParsers()
        {
            return _container.ResolveAll<IParser>();
        }
    }

    public class DefaultParser : IParser
    {
        public override string ToString()
        {
            return "DefaultParser";
        }
    }

    public class BasicParser : IParser
    {
        public override string ToString()
        {
            return "BasicParser";
        }
    }

    public class SuperParser : IParser
    {
        public override string ToString()
        {
            return "SuperParser";
        }
    }

    public interface IParser
    {
    }

    #endregion Resolve Demo
}

【问题讨论】:

    标签: c# unity-container


    【解决方案1】:

    您没有注册IParser 的3 个不同实现。您创建一个默认映射IParser -> SuperParser,然后用IParser -> DefaultParser 覆盖它,然后用IParser -> BasicParser 再次覆盖它。

    如果您想注册所有三个,您必须提供命名注册,例如

    container.RegisterType<IParser, SuperParser>("Super");
    container.RegisterType<IParser, DefaultParser>("Default");
    container.RegisterType<IParser, BasicParser>("Basic");
    

    另外ResolveAll 不包括默认映射(没有名称的映射)。它只解析那些注册为命名映射的IParser 映射。

    【讨论】:

    • 你知道不返回默认值是设计使然还是错误?
    • @NicolasIrisarri 除了至少从 v1.2 开始它就在代码库中,我相信它是设计使然。如果您使用名称(例如“default”)再次注册默认映射,您可以轻松解决它。
    • 这确实是很有价值的信息。以这种方式表现的统一没有任何意义
    • 我认为 Unity 真的应该抛出一个异常,而不是仅仅重写或者更好地使默认行为是 Unity 将注册的类型注册为名称。
    • @JonasStensved 其他容器默认记住多个注册,并使用它在解析时创建对象链。 Unity 会覆盖该注册。不同的容器,不同的行为。但是您可以随时扩展 Unity 以匹配您的偏好。
    【解决方案2】:

    如果您想解析容器中的所有解析器,您需要使用名称注册解析器。

    这是来自您的构造函数的更新代码:

    public ResolveAllDemo() 
    {
    
      var container = new UnityContainer();
    
      container.RegisterType<IParser, SuperParser>("SuperParser");
      container.RegisterType<IParser, DefaultParser>("DefaultParser");
      container.RegisterType<IParser, BasicParser>("BasicParser");
    
      container.RegisterType<IParserFactory, UnityParserFactory>();
    
      foreach (var registeredMember in container.ResolveAll<IParser>())
      {
         LoggingUtility.LogerInstance.Logger.Write(registeredMember);
      }
    }
    

    注意:

    下面的代码就不需要了,因为容器在构建容器的过程中会自己注册。

    container.RegisterInstance<IUnityContainer>(container);
    // not needed cause UnityContainer registers itself on construction
    

    【讨论】:

    • 谢谢你,你的回答真的为我今天的调试省了不少事!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多